Sunday, May 24, 2009

How to read a technical book

If you're anything like me, you've gone to a bookstore, found a good book on programming or some other technical subject, taken it home all eager to read it, and fallen asleep three pages into the second chapter. The book then finds a place in your bookshelf where you pick it up from time to time with renewed energy to read it from start to finish, and you get two pages further than your previous attempt. Eventually the book just ends up on your bookshelf and any technical brilliance within remains undiscovered.

I have a few tips to take more from these books:
  1. Open the book somewhere in the middle and start reading. The first few chapters usually contain filler material to pad out the number of pages. This filler involves justifying why the book exists and provides introductory information that you probably already know. If you open the book somewhere in the middle you will likely land right in the middle of the technical information you actually bought the book for. Read through one of these middle chapters and at the very least you will get a sense of what the book will eventually provide you if you restart reading from the beginning. Better yet, read that middle chapter in the bookstore before you buy it and you may save you some money.
  2. If you do read from start to finish, don't rush it. Take your time. Paper is a relatively robust medium and won't expire before you can absorb the information printed thereon. Reading a technical book is usually a marathon, not a sprint. In The Pragmatic Programmer the recommendation is to read one technical book per quarter; not per week or per day. It takes time to really read a technical book. Once you have developed a habit for reading technical books you can increase the frequency to per month if you so desire.
  3. Unless you are buying them for reference, don't buy books in bulk. Buy one at a time and read through it. Having more than one book to read can be a distraction.
  4. Don't be afraid to give up reading a book if it is just not doing if for you. This is risky as you might miss something that is presented later in the book. But if the cost of reading is not being repaid through information you are obtaining, feel free to put it down. I'd recommend flicking through the unread chapters to see if there is something that is informative.
  5. Actively read. Have a notebook and pen nearby and actively take notes of things you think are key in what you are reading.
  6. Related to the previous, have whatever you need to get hands on with a technology at hand as you read about it. Most technical books will include examples you can follow along with and exercises for you to do. Follow along with the examples by actually manually recreating them on your own computer. And do the exercises, don't just download the solutions from the books website. Do download later to review how the author completed them, but make an effort first.
Following these tips I have read more technical books in the past six months than I have in the past six years. Perhaps that says more about my character, but I honestly think I was sitting at about the median when it comes to programmers. I now feel I am slowly moving to the right in the bell curve.

Saturday, May 16, 2009

Entering Special Keyboard Symbols on a Mac

Keyboard keys like Tab, Control and Shift are occasionally represented in text using symbols. For example, Tab is represented as an arrow pointing right with vertical bar at its head. Each of these symbols is represented by a Unicode code point. Therefore, if you know the code point, and how to enter code points into your editors, you can make use of these symbols.

The first way to enter these symbols relies on you creating a HTML document. Code points can be entered as HTML entities in the form &#x<code point>;. This assumes the <code point> in its hexadecimal representation. The code point for the Tab symbol described above is 21E5 and looks like ⇥. Of course, whether you see the symbol correctly depends on your viewer's ability to interpret the HTML entity and display the corresponding symbol.

If you are not writing a HTML document, you can still insert these symbols (if your editor supports doing so). On a Mac this can be done via the following process:

1. Open System Preferences
2. Select International
3. Select Input Menu
4. Scroll to the bottom and check "Unicode Hex Input"

You should now have a little "U+" icon in your menu bar at the top right. With this enabled you can now enter symbols by typing the code point while holding the Alt/Option key.

That is pretty much it. I think a similar process is used on Windows.

Here is a list of code points for some of the keys on a Mac OS X keyboard.

KeyCode PointSymbol
Control2303
Alt/Option2325
Shift21E7
Command2318
Tab21E5
Backtab21E4
Return21A9
Enter2305
Delete2326
Backspace232B
Escape238B
Left Arrow2190
Right Arrow2192
Up Arrow2191
Down Arrow2193


TextMate's HTML bundle has tab triggered snippets for each of these symbols. To enter the Tab entity just type tab⇥.

Friday, May 15, 2009

TextMate Snippets for GPL3 Copying Statements

I have, somewhat arbitrarily, chosen GPL3 as the licence for my (as yet unwritten) new code. Instead of writing that code I have been yak shaving in the form of learning how to write TextMate snippets to insert the GPL copying statements (available from the GPL Howto page). Turns out it is not too hard to get something working quickly.

New snippets can be created via the Bundle Editor. I created a new bundle (via the '+' button at the bottom left of the Bundle Editor) and named it MyAutomations (innovative, what?). I want two snippets: one to insert the program in a single file copying statement, and the other to insert the 'this file is part of program' statement.

A new snippet is created via the '+' button in the bottom left. I name my first snippet 'GPL' and replace the default helper text with the appropriate GPL copying statement. Select the Activation to be 'Tab Trigger' and set the text to be 'gpl'. Closing the Bundle Editor saves the changes and typing gpl and then hitting tab correctly inserts the copying statement.

The second snippet is slightly more complicated as it includes the name of a program, something that will change from file to file. This is easily accommodated using tab stops. I created another snippet, this one named 'GPL Program', and choose Tab Trigger activation with an activation string of 'Gpl'. For the text to be inserted I use:

This file is part of ${1:ProgramName}.

$1 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

$1 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with $1. If not, see .
$0
The ${1:ProgramName} is the first, and only, tab stop. After typing Gpl and hitting tab, the default string 'ProgramName' will be highlighted with the cursor sitting, waiting for me to enter a proper program name. The other occurrences of $1 in the text mirror what is written here.

The final $0 is where the cursor ends up when I tab out after writing the program name.

Simple.

There are some enhancements I'd like to make:
  • If I type the tab trigger after a character or some text (like a comment character), i'd like all lines of the copying statement to begin with that text.
  • If I am editing source code, I'd like the copying statement to be prefixed with the appropriate comment character.
  • I'd like a snippet that just inserted a copyright statement and the copying statement in one go.
I'll work on these.

Wednesday, May 13, 2009

A bit more SCons

Today I tried creating a SConstruct file on a Windows box that was basically identical to the one I had running on my Mac, but it encountered problems with not finding compiler and linker tools. I spent a little while trying to debug the problem but decided I needed to get a broader understanding of how SCons works and what it provides. So, I printed out the User Guide and started reading.

However, I've just spent the last hour browsing the SCons Wiki and, in particular, the SCons Recipes. Had I consulted this page during my debugging I probably would have resolved my problem quickly. Having real world examples are always useful learning aids.

I am going to continue reading through the Users Guide as SCons is a technology I need to know well if I am going to use it effectively in my day-to-day activities.

Tuesday, May 12, 2009

SCons

I spent some of today looking at SCons as a build tool for (initially) my C++ code. After trying things out on some toy code I moved over to my main codebase that contains 10,000+ lines of code spread across 50+ files.

To date my build system has consisted of calling, from the command line, the MSVC++ executables on pre-established workspace/solution files. This becomes a real nuisance when I need to add new code to the project as it involves GUI manipulation to add each file to the project (true, I could edit the project files directly, but I don't know the specifics of the formats well enough to be confident my changes would be correct). Plus, I have to do this for multiple versions of MSVC++ that I still need to support. I tend not to use the MSVC++ IDEs to create and edit my source files and I have, more than once, added files to the filesystem and forgotten to add them to the project. So, one thing I wanted of SCons was to not have to update the build script if I added a new set of code to the source tree.

I wasn't able to locate a SCons function to do this for me directly. It seems the only source aggregation routines available in SCons work in a single directory. However, since SCons' build scripts are written in Python it was simple enough to create what I wanted. Here is the function I created (with help from Programming Python, 3rd Ed) to get a list of all source files in a source tree:


import os
def getSourceFiles(root_dir, source_file_extensions):
source_files = []
for (dirname, dirshere, fileshere) in os.walk(root_dir):
for filename in fileshere:
if os.path.splitext(filename)[1] in source_file_extensions:
source_files.append(os.path.join(dirname, filename)

return source_files


With this routine I can now compile a library of C and C++ code spread throughout a directory tree using the following SCons build script:


source_files = getSourceFiles('src', ['.cpp', '.c'])
Library('libname', source_files)


Nary a hard coded filename in sight.

An added advantage of SCons over MSVC++ is related to source files with the same name but in different directories. MSVC++ by default will try to generate the same object file for all source files with the same name, regardless of where they appear in the source tree. Manual intervention is required to have different files generate different object files. In contrast, SCons' default operation is to reflect the source directory tree in the build output.

So, after half a day of use, SCons is impressing me. However, I have only tested my build script on one computer (a Mac). Tomorrow I need to test on a Windows box and configure the script to selectively use VC6 or VC8.

Monday, May 11, 2009

Beginning

During the weekend I started work on my first programming project: an image viewer. My first task was to begin researching image codecs and file formats. Where do you think I looked first? Fifty points to those of you who said Wikipedia.

Specifically, I read through the article on the JPEG codec. I had researched this codec a little during a signal processing course at university and it was good to refresh the neurons. For example, I was aware that after the discrete cosine transform has occurred, a lossless compression algorithm is run over the coefficients. The article pointed me to the specific algorithms defined for use in the JPEG codec: Huffman coding and arithmetic coding. So, to implement the JPEG codec I first have to implement one of these algorithms. I will implement Huffman coding as I am not completely sure that arithmetic coding is free of patent issues. Huffman coding is also used in the bzip2 data compression algorithm which I plan to implement at some point.

However, before I get into the weeds of design and coding I want to take two sidetracks to explore some tool functionality. Specifically, I want to look at creating my own templates or snippets for TextMate that will insert appropriate licence comment blocks in my source code, and I want to read and experiment a little with Scons to be used as my build tool.

Saturday, May 9, 2009

Programming Tasks

Here is a list of programming tasks I will tackle to gain further experience in developing software:
  • Image viewer (JPG, BMP, PNG).
  • Compression utility (BZ2, GZ, ZIP (unless patent encumbered))
  • Movie player
  • Delicious Library for recipes
  • Tetris clone
  • A plugin for something
  • An HLA OMT editor
As part of writing these application I want to learn about the domains as well. This means that in writing these applications I will not use libraries that are directly applicable to the task. For example, I intend to write my own JPG encoding and decoding routines. The point here is to learn on the journey, not reach the end as quick as possible.

Along the way I will be thinking about diverse topics from using my programming tools to software development processes. I will write about my experiences, success, failures, and even tips on using tools as I go along.

If you have suggestions for additional programming tasks, please let me know in a comment.

For now, on with the image viewer.

Thursday, May 7, 2009

I'm Back

A long time between posts. Not really a novel thing for me. But this time I have some sort of excuse.

I spent most of March and April in Jakarta, Indonesia; my wife's home town. We were back there to apply for my wife's spouse visa. The embassy's website states that spouse visa applications average 3--5 months to process. We put a lot of work into ours. We asked questions about what to submit and completed some tasks before submitting the application where others would wait to be asked by the embassy. I also wrote a 23-page supporting letter full of photos that we printed in colour. The upshot of all this is that a decision was made on my wife's visa in two days and she was granted her visa. We are back in Australia now and getting on with life.

The last weeks before we left for Jakarta were hectic for us. I had a couple of dentist's appointments, I submitted my PhD thesis and had a promotion interview at work. We also were preparing my wife's visa application, completing the medical check up and getting documents certified. Now, two months later, I still have dentist's appointments and I haven't heard anything about my thesis, but I did get the promotion.

But for the first few weeks in Jakarta, when we were finalising the visa application, our time for those two months was fairly relaxed. I spent most of the time keeping my 9-month old niece company and trying to keep her from hurting herself. An amusing time. She seemed to get louder by the day; and, now that we have left, we have been told that the house is much quieter.

I did get to do some reading on Objective-C and iPhone development. I worked through some exercises in two texts: Learn Objective-C on the Mac and Beginning iPhone Development.

Now I feel like getting back into some focused software development in my spare time. I've written before (I think) that a hallmark of my programming to date has been its incompleteness. I want to set myself some well-bounded applications to develop and see them through. I'll list the applications I am thinking about in my next post.