Friday, December 23, 2011

Design Patterns Refresher

The most common design patterns from "Head First Design Patterns" by Eric Freeman and Elisabeth Freeman - the best book ever about design patterns:

Encapsulate algorithms. Allows object's behaviour to be changed at runtime by substituting default algorithms. 

Notify dependents of state changes. A very common pattern, often part of the language, see events and listeners in C#.

Use and extend behaviour of the object being wrapped, while acting as that object to the external world. A decorator object is created with an instance of an object of the same type. When a method is invoked, it calls the embedded object's method, modifies the result, and returns it.

Simple Factory
Encapsulate object creation. Useful when you need to decide at runtime which object to create.

Factory Method
Same purpose as Simple Factory, but more abstract: moves actual object creation to other factory objects. 

Indispensable when there is one of something in the system, like one database, or one set of configuration data. Implemented as a sealed class with private constructor and a static method that returns the only instance.

Encapsulate actions. Every action object has "execute" method. Very useful for a processing system that needs to queue commands and then execute them in order. 

Provide a converter that allows clients to use the interface they expect with an object that has a different interface.

Provide a simplified interface. Used to hide complexity of the underlying system from the external world.

Template Method
Provides extension points or hooks by defining steps of an algorithm and allowing or forcing subclasses to provide implementation for some of them. This pattern is often used in frameworks.

Provides a uniform way of accessing sequentially elements in an aggregate object of any type. Typically found in collections.

Organize objects into tree structures so a group of them can be treated the same way as a single element. Each object in the hierarchy is a component that can have sub-components. User interfaces are usually built as composites.

Encapsulate behaviours of an object in state objects. Current state object can request transition to another state.

Provide a surrogate object that controls access to an object that is remote, needs to be secured or is expensive to create.

Saturday, December 17, 2011

Forgetting is the key to AI

I think that making computer programs fortget most of what they receive is the key to building Artificial Intelligence. Why? Because having to much data creates three problems:

1. Space needed to store it.
2. Speed of retrieval.
3. Classification: which piece of data is important?

Selective forgetting would solve these problems.

Spaced repetition algorithm should be used backwards to achieve that goal: when the AI program sees something for the first time, it keeps it until the next day. If it sees it again the next day, it keeps it for 6 more days. If by then it sees it again close to the 6th day, then it keeps it for another 15 days,  and so on. When something stops occurring, it is gradually forgotten. So, the AI program keeps less data, so the information can be retrieved faster, and the data kept is important in understanding the environment, because it keeps coming.

This mechanism works ok with the AI program learning about normal situations. It may stumble upon extraordinary, life-threatening situations, which need to be remembered separately from the spaced repetition algorithm.

Wednesday, November 30, 2011

Do you speak English, mate?

It's been almost a year since I moved to Australia, but I'm still being surprised almost every week by some cute Australian abbreviation for the long and boring English word. A few examples:
a postie - postman
a tradie - tradesman
a bikie - a member of a motorcycle gang
the ambos - ambulance personnel
a kindy - kindergarten
the crims - criminals
a journo - journalist
a doco - documentary
a sickie - sick leave
a fisho - seafood shop
a rego - car registration
a compo - compensation
a uni - university
a footie - football game
a garbo - garbage man - in our city, the garbage truck is operated by one man who drives the truck and picks up garbage using a remote arm - very XXI century
a schoolie - student on a final school break after graduating from high school
a truckie - truck driver
a ute - pick-up truck, for some strange reason it is cool to have one with low suspension, aluminium rims, two exhaust pipes, and dark windows.... are they prized by crims for easy loot loading?

Some other differences between everyday Australian and American English that may trip you out:
to chuck out - throw away
a rubbish bin - waste basket
a cash out - cash back
a bashing - beating
the thongs - flip-flops (for American readers: thongs are called g-strings in Oz, and they may draw a blank if you mention flip-flops)
relief teacher - substitute teacher
super - 401k
a council - town or county government

All over the town you can see signs that may make most American visitors smile:
Dick Smith - a chain of electronics shops.
LJ Hooker - a chain of real estate agents.

The word "mate" is used where "man" or "sir" would be used in the States.
The word "cheers" is used where "thanks" or "bye" would be used in the States.
The "shopping mall" is more commonly known as "shopping centre".

Australians write "kind regards" in e-mails where Americans would put "best regards".
I haven't heard anyone say bullsh#t, but sh#t is heard quite often.
I almost never hear "bless you" when someone sneezes, and almost never hear politicians referring to God. It may be related to the low importance of religion in general. Australian Roman Catholic Churches, new or old, are miniatures of their American counterparts.

The pronunciation may be peculiar : Super is often pronounced and written as "supa", doctor is often pronounced "docta". Strangely, I did not see a single "nite" or hear "wanna", "gonna", "gotta" or "ain't".

Some other general (subjective, subject to change, and not to be taken dead serious) observations:

Australians are very punctual and it's contagious as demonstrated by the fact that most Poles living in Australia tend to be punctual. That doesn't mean that things get done quickly. Although new laws are introduced very swiftly compared to the US.

Bureaucracy is alive and well. Things often get done slowly and costly, maybe after a number of failed attempts, but surely - they DO get done. Australians love filling forms. They must do. How else to explain these hundreds of pages that I had to go through to rent a house, open a bank account, register with Centrelink, buy a car, sign up the child for school, keep the child at school, and last but not least do taxes? On the other hand, medical forms are minuscule in Australia compared to the US.

Australia surprises me sometimes by giving for free things I expect to pay for elsewhere, and for paying for things I expect to be free. For example, my child went with the school choir to sing in a shopping centre. In the States, the school would get some donation from the shopping centre for that. In Australia, parents paid for the bus. Children and parents at my daughter's elementary school must buy tickets to go to the official end of school year event. On the other hand there are great free libraries with CDs, DVDs, computer games, and books and movies in foreign languages. At work, I have to buy and wear company polo shirts to come to office in jeans, but I get free breakfast everyday, and beer, wine, and snacks every Friday afternoon. There are free council events including movies in the park and various classes. You are never too far away from a free public park with playgrounds, toilets, and barbecues.

Australians love challenge and a chance to beat the odds. Sailing solo around the world? An Australian girl can do it. Getting in and out of the parking garage without a scratch? The designers and builders put a lot of effort into making the spaces and corners as tight as possible. Most Australians pass, the paint and grooves on the concrete walls are the fault of the tourists, probably Americans. Parking in your own garage? Again, the designers and builders made sure that in many homes you need a 4 wheel drive to get up the driveway, and then when you get to the top you either stop in place or turn 90 degrees to park. Trying to get on the motorway? You turned right to go right or you went straight to go straight? Wrong decision mate, you will have at least 3 kilometres to rethink that and try your luck at getting back on the motorway in the right direction.

Many Australians speak softly. In my first work meeting in Australia I was confused for a while, because I didn't notice that it started. The person chairing the meeting spoke so quietly that I thought it was a private conversation.

Australians love America, except those who don't. But most do. I think. Julia likes Barack very much.

Australians make great mainstream TV shows and movies about life (that includes sex): Satisfaction, The Slap, and about controversial subjects: Go Back to Where You Came From.

Australians have high quality public radio and television without irritating fund-raising drives.

Australians have a sense of humour. The public TV made a comedy about the current prime minister: At Home With Julia.

On a more serious note. I noticed that Australians are able to take with a smile various misfortunes: floods, fires, being robed, being demoted, being bitten by a jelly fish, spraining an ankle, long commute, expensive living, low quality housing and so on.

The sight of multiple families having a picnic, preparing a hot meal on a barbie in a park, sometimes right by the beach is a very Australian scene for me. Another is people, not just children, sometimes walking barefoot in shopping centres or in the city, but you can see that in New Zealand too, so what do I know?

Cheers mate!

Sunday, October 16, 2011

The Code Book by Simon Singh / The proof that we are a simulation

The Secret History of Codes & Code-breaking.

Simon Singh takes us on a journey through ages: from the cipher of Mary Queen of Scots, through Enigma, public key cryptography to quantum cryptography. He reveals the history of code making and code breaking.

The Code Book is not just about history. It is a study guide, too. Everything is illustrated with examples, formulas, and diagrams. Simon has a gift of describing frequency analysis, one way functions and even quantum computing in an simple way.

The Code Book is a great read. Highly recommended.


There is one thing in The Code Book, which may be interpreted as a proof that we live a computer simulation. It is about Thomas Young's experiment with a light source, a partition with two slits, and a screen. That experiment shows the wave nature of light. Waves of light reinforce or cancel each other producing multiple stripes on the screen. But nowadays we can send just one photon, wait for a minute, then send another, again wait, send another and so on. In this case, should we see multiple stripes on the screen or just two? Each photon that we send has no other photon to interact with, so it should behave like a particle and just go through one of the two slits. There should be only two stripes on the screen.

Simon writes: "However, for some extraordinary reason, even with single photons the result on the screen is still a pattern of light and dark stripes, just as if photons had been interacting." There are two scientific theories currently that try to explain it: superposition and multiverse. Either the photon passes through both slits simultaneously and then interacts with itself - that's superposition, or the universe splits into two which interfere with each other - that's multiverse.

Well, I'm a programmer, and from my point of view it looks like a silly bug. If I was designing the universe, I could easily make an error of assuming that the characters in my world would never get smart enough to send a single photon, so I would take a shortcut and compute the pattern as if photons were sent continuously. It's a simpler explanation than superposition or multiverse, isn't it? :-)

I need to learn more about photons.

Tuesday, October 4, 2011

Washington, DC

Originally posted 2010-04-18.

During this spring break we went on a trip to Washington, DC. After a long winter the flora was eager to flourish again. A thick layer of pollen was obstructing visibility and making life difficult for people with allergies all the way from Florida to DC.

In South Carolina we saw this fine specimen of Luna Moth.
 We spent most of the time in Washington around The Mall - the downtown area where most important institutions of the U.S. government are located.

Here is one of them, the well known classical Capitol building.


The most famous museums in Washington belong to the Smithsonian Institution, and the most famous of them is the Air and Space, which takes pride in the quality of their artifacts: it showcases only originals in perfect condition. The admittance is free and the guided tours are excellent. Here are some examples of what is on display.

A nose section of Boeing 747.

The Enterprise orbiter. Smithsonian will get a real space shuttle after they are retired by NASA, if it can find the 20 something million dollar fee NASA wants for shipping and handling.

The retired British-French supersonic passenger jet - the Concorde.

Do you know why the windows are so tiny? It's because Concorde was flying much higher than other passenger jets, and if it lost a regular sized window, it would not be able to descend to safe height before suffocating everybody on board.

Enola Gay is the name of a B-29 plane that dropped an atomic bomb on Hiroshima. This specimen, like all others at Smithsonian, is an original.


The underside of a Predator UAV.

Finally, the UAVs. Boeing X-45 was an experimental Unmanned Aerial Vehicle. UAVs are the future of military aircrafts.

Our volunteer guide, a retired pilot, said that the F-35s are probably the last manned fighters the U.S. will produce.

Some less known museums and attractions.

Botanical Gardens near the Capitol.

The Building Museum was originally a home to the U.S. Pension Bureau headquarters.

Imagine that floor with a fountain in the middle, and plenty of air and natural light filled with desks.

This is what I call a decent office space.

The Basilica of the National Shrine of the Immaculate Conception - the largest Roman Catholic church in North America.

Ghostly Korean War Memorial.

The Postal Museum located near the Union Station is new and surprisingly interesting. You can learn that parts of U.S. Route 1 were originally a trail used by native Americans, and later by mail riders.  You can learn that pneumatic mail delivery systems were operating in major U.S. cities in the XIX century.

U.S. Mail travelled under the seat of the driver of that stagecoach.

An ingenious postal snow mobile.



On the way back to Florida, we stopped again in South Carolina and visited Patriots Point Naval and Maritime Museum near Charleston.

Slowly deteriorating USS Yorktown aircraft carrier at Patriot's Point in South Carolina.

Towards the end of the war, the kills consisted mainly of trains, planes on the ground (sitting ducks), and ships.

The legend for the stats.

International maritime signal flags.

Most planes on USS Yorktown are displayed with their wings folded allowing us to peek into the folding mechanism.

Japan - Tokyo, Yokohama - First Impressions

Originally posted 2008-03-22. 

First impressions:
Long lines for passport control for foreigners at Narita Airport. I have waited for about 45 minutes. After the passport control everything went much smoother:

It was easy to use a public phone.
It was easy to buy a bus ticket.

On the bus journey to Tokyo my main impression was that Tokyo was more similar to European cities and thus more familiar to me than most of the U.S. cities I have seen:

The sidewalks made from pavers and actually used by people to walk.
The maximum use of space.
The trees planted in the sidewalks despite their narrowness.
The Carrefour and IKEA shops.
The buses and the trains.
The metric system: standard road signs in kilometers, temperature in degrees Celsius.

Small things.

The east entrance to the Imperial Gardens in Tokyo. The Imperial Palace is not visible from any point. The emperor does not wish to be disturbed.

Shin-Yokohama means new Yokohama. The Shinkansen stops at Shin-Yokohama. Tokyo Central is only two stops away.

This is a picture of one of the 3 types of Shinkansen trains operated by JR Tokai. I love these trains: fast, quiet, safe, comfortable.

   The view of Tokyo from the Tokyo Tower.

Monday, October 3, 2011


Originally posted 2008-04-17.

Author: Richard North Patterson
Category: Fiction
Ready by: Dennis Boutsikaris
CDs: 17

A very objective look at the Israeli-Palestinian conflict. You will listen to many disturbing stories. You will hear from people living in that divided strip of land, talking about their rationales for living there, occupation, suicide bombings, hatred of others. Few will talk about their hopes for life in peace.

The author, Richard North Patterson prepared very well. He visited Israel and Palestine. He talked to influential people.

The fictional story is about David Wolfe and Hana Arif.  He is a US citizen and a Jew. She is a Palestinian. They studied together law at Harward, but their ways parted afterwards. They meet again after 13 years and that's all I can say without  giving up the plot.

The book is very captivating, especially towards the end. I did not mind traffic jams at all while listening to the story.

The narrator, Dennis Boutsikaris is very skilled allowing you to immerse in the story and almost forget that all voices come from the same person. Female voices sound a bit harsh, but maybe it was intentional.

Danny Deckchair

Originally posted 2009-12-20.

Category: Romantic Comedy
Actors: Rhys Ifans, Miranda Otto, Justine Clarke
Screenplay: Jeff Balsmeyer
Director: Jeff Balsmeyer
Year: 2003

Running Time: 1 hour 40 minutes

Rhys Ifans plays Danny Morgan, a cement man in Sydney who desparately needs his vacation. Unfortunately, his partner Trudy Dunphy, played by Justine Clarke, does not share his love for rustic camping. She would rather stay in the city and pursue her career and a more important man.

Danny Deckchair is a refreshingly light, intriguing, story of finding one's place and mate. Highly recommended, especially when feeling down.

The PG-13 rating in the U.S. is nuts. This is a PG movie.


Originally posted 2008-04-19.

Category: Comedy
Actors: John Cleese
Screenplay: Michael Frayn
Year: 1986

Running Time: 1 hour 36 minutes

John Cleese plays Brian Stimpson - a headmaster obsessed with punctuality. His school resembles a workcamp with principal Stimpson keeping an eye on everyone from his watch-tower.

His few vices include not paying attention to what people say and overusing the word "right", right?

This light comedy is a pleasure to watch. Not overdone. Not boring. Not irritating. Just right.

Playing for Pizza

Originally posted 2008-06-18.

Author: John Grisham
Category: Fiction
Read By: Christopher Evan Welch

I do not know much about American football, but the story of an extremely unlucky NFL player Rick Dockery is still captivating.

Playing for Cleveland Browns, Rick makes 3 mistakes in a matter of minutes, and lands unconscious in a hospital. He's fired. Browns fans want to kill him...  

John Grisham likes Italy. This is his second book I listened to, that takes place mostly in Italy. He likes the food, the people, the clothes, the way of life. I like it too. It is hard not to. 

Predictably Irrational - The Hidden Forces That Shape Our Decisions

Originally posted 2010-03-07.

Author: Dan Ariely
Category: Popular Science
Read By: Simon Jones
CDs: 6

Refreshing, if not groundbreaking, look at human behavior in the context of economics.
Dan Ariely writes about results of real, clever and meaningful research experiments in a very approachable way.
Even though this is a truly scientific book, it has very practical implications for regular consumers like you and me. Make sure you read it before making your next big purchase. An eye opener.

For all chapter overviews go to wikipedia: Predictably Irrational

Highly recommended for adults. Contains details of reasearch about human sexuality that may not be appropriate for young readers.

Huffman's compression algorithm implemented in JavaScript

Originally published 2009-06-02, on

The other night I have implemented Huffman's compression algorithm in JavaScript. Here is a wiki link describing what Huffman coding is:
Huffman coding
Here is my JavaScript implementation:
<title>Huffman's compression algorithm implemented in JavaScript 
by Tomasz Andraszek</title>
<script type="text/javascript">
function compress() {
 var input = document.getElementById("input").value;
 document.getElementById("inputlength").innerHTML =input.length*8;
 var probabilities = getProbabilities(input);
 var codes = getCodes(probabilities);
 var output = compressHuffman(input, codes);
 var temp = "";
 for (var elem in probabilities) {
   temp += elem + " = " + probabilities[elem] + "<br/>";
 document.getElementById("probabilities").innerHTML = temp;
 temp = "";
 for (var elem in codes) {
   temp += elem + " = " + codes[elem] + "<br/>";
 document.getElementById("codes").innerHTML = temp;
 document.getElementById("output").innerHTML = output;
 document.getElementById("outputlength").innerHTML =output.length;

function sortNumberAsc(a, b) {
 return a[1] - b[1];

function getCodes(prob) {
 var tree = new Array();
 var secondTree = new Array();
 this.getNext = function() {
 if (tree.length > 0 && secondTree.length > 0 
               && tree[0].prob < secondTree[0].prob)
   return tree.shift();
 if (tree.length > 0 && secondTree.length > 0 
                && tree[0].prob > secondTree[0].prob)
   return secondTree.shift();
 if (tree.length > 0)
   return tree.shift();
 return secondTree.shift();
 var sortedProb = new Array();
 var codes = new Array();
 var x = 0;
 for (var elem in prob) {
   sortedProb[x] = new Array(elem, prob[elem]);
   x = x + 1;
 sortedProb = sortedProb.sort(sortNumberAsc);
 x = 0;
 for (var elem in sortedProb) {
   tree[x] = new node();
   tree[x].prob = sortedProb[elem][1];
   tree[x].value = sortedProb[elem][0];
   x = x + 1;
 while (tree.length + secondTree.length > 1) {
  var left = getNext();
  var right = getNext();
  var newnode = new node();
  newnode.left = left;
  newnode.right = right;
  newnode.prob = left.prob + right.prob;
  newnode.left.parent = newnode;
  newnode.right.parent = newnode;

 var currentnode = secondTree[0];
 var code = "";
 while (currentnode) {
  if (currentnode.value) {
   codes[currentnode.value] = code;
   code = code.substr(0, code.length - 1);
   currentnode.visited = true;
   currentnode = currentnode.parent;
  else if (!currentnode.left.visited) {
   currentnode = currentnode.left;
   code += "0";
  else if (!currentnode.right.visited) {
   currentnode = currentnode.right;
   code += "1";
  else {
   currentnode.visited = true;
   currentnode = currentnode.parent;
   code = code.substr(0, code.length - 1);
 return codes;

function node() {
  this.left = null;
  this.right = null;
  this.prob = null;
  this.value = null;
  this.code = "";
  this.parent = null;
  this.visited = false;

function compressHuffman(input, codes) {
  var output = input.split("");
  for (var elem in output) {
   output[elem] = codes[output[elem]];
  return output.join("");

function getProbabilities(input) {
  var prob = new Array();
  var x = 0;
  var len = input.length;
  while (x < len) {
   var chr = input.charAt(x);
   if (prob[chr]) {
    prob[chr] = prob[chr] + 1;
   else {
    prob[chr] = 1;

  for (var elem in prob) {
   prob[elem] = prob[elem] / len;
  return prob;

Type in the text to compress here:<br />
<textarea id="input" rows="5" cols="80">aaabcc</textarea><br/>
<input type="button" onclick="compress()" value="Compress" /><br/>
Text's length (8 bits per character): <span id="inputlength"></span><br/>
Probabilities of all distinct characters in the text:<br />
<span id="probabilities"></span><br/>
Binary codes assigned to characters: <br /><span id="codes"></span><br/>
Binary output: <span id="output"></span><br/>
Output's length in bits: <span id="outputlength"></span><br/>

Enums in JavaScript

Originally published 2008-12-27, on

JavaScript does not support enums like these in C#:
        enum SpriteSize
            Small = 100,
            Big = 200
        void Render(SpriteSize spriteSize)
            if (spriteSize == SpriteSize.Small)
            // TODO: implement

The simplest way to get enum functionality in JavaScript is to create a variable using JSON:
<script type="text/javascript">
            var SpriteSize = 
                Small: 100,
                Big: 200

            function Render(spriteSize)
                if (spriteSize == SpriteSize.Small)
                // TODO: implement

Hunting Deadlocks - SQL Server 2000

One of a series of posts from posted originally between 2006 and 2010. 

A typical scenario for a deadlock is described in Books Online: two procedures which try to use two tables in a different order, block each other after aquiring a lock to the first table.

I will describe here a different scenario: one procedure using one table. How can a deadlock occurr in such a case? Let's see.

It all starts with SQL Error 1205: Your transaction (process ID #99) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun your transaction.

First, let's enable SQL Server Trace 1204 flag. You must be in sysadmin server role to execute the following statement:

The trace, by default is written to this file:
C:\Program Files\Microsoft SQL Server\MSSQL\LOG\ERRORLOG

Here we find details of our deadlock:
Deadlock encountered .... Printing deadlock information
2004-10-15 19:14:04.64 spid4
2004-10-15 19:14:04.64 spid4 Wait-for graph
2004-10-15 19:14:04.64 spid4
2004-10-15 19:14:04.64 spid4 Node:1
2004-10-15 19:14:04.64 spid4 KEY: 10:1266375687:3 (dd0025eb9a53) CleanCnt:1 
Mode: S Flags: 0x0
2004-10-15 19:14:04.64 spid4 Grant List 1::
2004-10-15 19:14:04.64 spid4 Owner:0x655ac660 Mode: S Flg:0x0 Ref:1 
Life:00000000 SPID:75 ECID:0
2004-10-15 19:14:04.64 spid4 SPID: 75 ECID: 0 Statement Type: SELECT Line #: 29
2004-10-15 19:14:04.64 spid4 Input Buf: RPC Event: InvoiceUpdate;1
2004-10-15 19:14:04.64 spid4 Requested By:
2004-10-15 19:14:04.64 spid4 ResType:LockOwner Stype:'OR' Mode: X SPID:64 
ECID:0 Ec:(0x63B3F580) Value:0x57648ee0 Cost:(0/3C)
2004-10-15 19:14:04.64 spid4
2004-10-15 19:14:04.64 spid4 Node:2
2004-10-15 19:14:04.64 spid4 KEY: 16:1153035489:1 (d1003ffe1113) CleanCnt:1 
Mode: X Flags: 0x0
2004-10-15 19:14:04.64 spid4 Grant List 0::
2004-10-15 19:14:04.64 spid4 Owner:0x42bc2140 Mode: X Flg:0x0 Ref:0 
Life:02000000 SPID:64 ECID:0
2004-10-15 19:14:04.64 spid4 SPID: 64 ECID: 0 Statement Type: UPDATE Line #: 
2004-10-15 19:14:04.64 spid4 Input Buf: RPC Event: InvoiceUpdate;1
2004-10-15 19:14:04.64 spid4 Requested By:
2004-10-15 19:14:04.64 spid4 ResType:LockOwner Stype:'OR' Mode: S SPID:75 
ECID:0 Ec:(0x61D09580) Value:0x655ad200 Cost:(0/0)
2004-10-15 19:14:04.64 spid4 Victim Resource Owner:
2004-10-15 19:14:04.64 spid4 ResType:LockOwner Stype:'OR' Mode: S SPID:75 
ECID:0 Ec:(0x61D09580) Value:0x655ad200 Cost:(0/0)

You can notice that both nodes executed procedure InvoiceUpdate. From the KEY you can decipher the object they fought for:
10 is database id,
1266375687 is table id,
and 1 or 3 are index ids.

Find name of the database:
SELECT [name] FROM master.dbo.sysdatabases WHERE dbid = 10

Find name of the table:
SELECT OBJECT_NAME('1266375687')

This may be a temporary object, for example a cursor, which will not exist when we check later. In this case find name of the table from the stored procedure: just look for line # provided by trace.

There is a little trap here: if your procedure calls another procedure, then the deadlock may actually occurr in the subprocedure and the line number applies to the subprocedure.

Find ids and names of the indexes:
SELECT indid, [name] FROM sysindexes WHERE id = OBJECT_ID('Invoice')

Find keys of the indexes:
sp_helpindex 'Invoice'

Both instances aquire a shared lock to a range of rows, and then one of them tries to escalate that lock to exclusive to update a row, but cannot, because the other keeps it and also tries to escalate to exclusive to update another row.

The problem is that the initial shared lock was too wide. The index used was not optimal for the SELECT statement and too many rows were locked.

The solution is to create another index which matches exactly the WHERE clause used in the SELECT. This of course does not solve the problem if there are two or more processes that try to execute this procedure with the same parameters. The application has to be designed in a way that processes operate on different sets of data.

Static Methods and Their Variables - .NET 1.1

One of a series of posts from posted originally between 2006 and 2010. 

Have you ever wondered about local variables of static methods? Are they static too? Or are they call-specific? What happens with the variables when a second thread calls the method while the first has not finished executing it yet? The code below allows examining this.

// You may need to run this C# .NET console application 
// a few times before you get interesting results
// Have fun!
using System;
using System.Threading;

  class StaticMethodExample
    public static void ShowXTwice ()
      // Uncomment the line below to see what happens if only one thread at 
      // a time is allowed to use type StaticMethodExample
      // Observe the average number of ticks go up
      //lock (typeof(StaticMethodExample))
      Random r = new Random();
      // Although the ShowXTwice method is static, each thread has its own instance of x
      // otherwise, all threads would use the same variable
      // and as a result sometimes x would have a different value when checked for the 
      // second time.
      // For example: x checked for the first time by thread 1 (x=123), then thread 2 
      // assigns a new value to x (x=456), and now thread 1 checks x for the second time
      int x = r.Next(1, 10000); 
        + " Checking x for the first time:  " + x.ToString());
        + " Checking x for the second time:  " + x.ToString());

  class TestStaticMethodExample 
    public static void Main() 
      int maxThreads = 100;
      Thread[] threads = new Thread[maxThreads];
      for (int i = 0; i < maxThreads; i++) 
        Thread t = new Thread(
                       new ThreadStart(StaticMethodExample.ShowXTwice));
        t.Name = "Thread " + i.ToString();
        threads[i] = t;
      long startTicks = DateTime.Now.Ticks;
      for (int i = 0; i < maxThreads; i++) 

      // wait for all threads to finish
      for (int i = 0; i < maxThreads; i++) 
      long endTicks = DateTime.Now.Ticks;

      Console.Write("Number of ticks from start to end: ");
      Console.WriteLine(endTicks - startTicks);
      Console.WriteLine("Press Enter");


Here is the output:

Unintuitive syntax - ABAP 4

One of a series of posts from posted originally between 2006 and 2010. 

Here is an example of a twisted "colon and comma" logic from SAP ABAP 4 programming language:

                    PHONE = '+48 22 1234567' 
              WHERE ID = '000899888'. 

This statement will update CITY for all rows and PHONE for the row with ID = '000899888'. The reasoning behind this is that by putting a colon we actually start defining statement chains: statements separated by commas. The whole thing ends with a full stop, which marks the end of every statement in ABAP 4.

This concept will be very weird to all SQL programmers.

Custom SQL Server 2005 Aggregates

One of a series of posts from posted originally between 2006 and 2010. 

Custom aggregates are as fast as built in T-SQL aggregates like MAX(), SUM(), etc..
Here is the C# source code for an aggregate that concatenates short strings:

using System;
using System.Text;
using System.IO;

using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

	Format.UserDefined, //use clr serialization to serialize the intermediate result
	IsInvariantToNulls = true, //optimizer property
	IsInvariantToDuplicates = false, //optimizer property
	IsInvariantToOrder = false, //optimizer property
	MaxByteSize = 8000) //maximum size in bytes of persisted value

public struct Concatenate : IBinarySerialize
  private StringBuilder _IntermediateResult;
  // 8000 - 2 control bytes - 4 bytes for 2 UTF-16 characters = 7994
  private const int _MaxSize = 7994; 

  public void Init()
    _IntermediateResult = new StringBuilder();

  public void Accumulate(SqlString value)

    if (!value.IsNull 
      && (_IntermediateResult.Length + value.GetUnicodeBytes().Length 
          < _MaxSize))
          _IntermediateResult.Append(value.Value).Append(", ");

  public void Merge(Concatenate group)
    if ((_IntermediateResult.Length + group._IntermediateResult.Length) 
      < _MaxSize)

  public SqlString Terminate()
    string output = String.Empty;
    // Delete the trailing comma and space, if any
    if (_IntermediateResult != null && _IntermediateResult.Length > 1)
      output = _IntermediateResult.ToString(0, _IntermediateResult.Length - 2);
    return new SqlString(output);

  public void Read(BinaryReader reader)
    _IntermediateResult = new StringBuilder(reader.ReadString());

  public void Write(BinaryWriter writer)

And here it is in action:

CREATE AGGREGATE Concatenate (@input nvarchar(4000)) RETURNS nvarchar(max)
	EXTERNAL NAME SqlClr.Concatenate

SELECT Title, dbo.Concatenate(FirstName) AS [First Names] 
	FROM Person.Contact 

Title    First Names
-------- ---------------------------------------------
Sr.      José, Jésus, Anibal, José, Luis, Gustavo, Ciro, Humberto, Alvaro, Adrian, Ramón
Sra.     Janeth, Pilar, Janaina Barreiro Gambaro

The law is a poorly written program/application/system

Originally published 2005-12-08, on

It struck me today that the written law is very similar to a poorly written program.

All these "the aforementioned party" and "the other party" and "with the exception of article 9, 5 and 6", and the sentences half page long, and references to other papers cropped all over ...

Do you remember BASIC with the GOTO statement or the assembler language? Now obfuscate it: remove all comments from that code. Replace all subroutine names with numbers, put extra GOTOs, and voila: you have the tax code.

The difference is: the user of the BASIC code - someone who plays a computer game for example - cannot be put to jail for not knowing and understanding every line of the computer code. The tax code user - can.

There are hundreds of thousands of lines of tax code, and they, as a system, change all the time. Why on Earth, we - the users - are obliged to know, understand and keep track of that? Give it to machines instead of us, lawyers, and judges. Give it to the Common Language Runtime. Let it analyze all references. Let it break trying to compile it. Let it freeze before displaying a verdict...

Old web sites

About a month ago, I've cancelled my old 1and1 domains and web hosting. The following web sites are gone:,,

I will re-post some old material here.

Wednesday, September 21, 2011

Introducing Membricks

Membricks - A spaced repetition game.

Spaced repetition is a key to effective learning. To learn thousands of facts in limited time you have to be efficient. You have to minimise time spent on repetitions. The idea is simple: a program calculates optimal repetition interval for every question and answer pair based on how difficult that pair is for you and how many repetitions you already had. The optimal interval is the longest one in which you still remember the answer. If you still can recall the answer, the next interval will be longer. If you can't, the next interval will be shorter and it will take you a while to get back on track.

I became a believer in spaced repetition about 15 years ago when Supermemo, a precursor of Anki, Mnemosyne, and other spaced repetition programs, as if by magic, made me remember hundreds of difficult Russian words for my Russian course at university. Since then, I tried to use spaced repetition programs to learn new things, but I was always abandoning my attempts quickly. Without an immediate need, it was difficult to keep the regime of daily sessions. Spaced repetition programs are quite boring and until a few years ago you usually ran them on a desktop or laptop computer. That meant that often when you had some spare time you couldn't learn, and when you could learn you didn't want to.

Membricks is my attempt at making a spaced repetition program more attractive and easily accessible. How? By making it an iOS game. My iPhone is with me all the time, so I will be able to use any spare minute to play, ahem... I mean learn. Membricks will be a competitive game. I will try to keep my score high against other players. My score will be going down every day I don't play. Scores will be kept on for everyone to see, just like in the old-fashioned video games.

I started developing Membricks in July this year inspired by an old book by Len Walsh for learning Japanese. That great little book describes the meaning of 300 most common Kanji characters by showing how they evolved from a drawing of a thing or concept to the current character. My thought was: this can be animated, and it can be made into a game. I have two little helpers: one is creating animations of these Kanji characters, and the other is working on sets of questions and answers for the first 3 decks: Kanji/English, English/Polish, and French/English. I am working on the code.

To be continued...

Wednesday, May 11, 2011

World's Greenest Homes

World's Greenest Homes series 1 was produced by Cineflix in 2008.  Every episode shows two, supposedly ecological, homes. I wrote supposedly, because you cannot seriously think that 400-700 square meter mansions for 2-5 people are ecological. It doesn't matter that you put concrete floors with garbage in them, or fill your walls with old newspapers, or use old furniture, or use rain water to flush toilets - you are still building a palace!

The host Emmanuel Belliveau is trying hard to find something ecological about those homes, but sometimes it feels like dual flush toilets or double-pane windows make your house "world's greenest".  

Most of the homes presented are in North America. With a few exceptions, they are huge, and they don't belong in this series. The homes that are in the UK, Sweden, Netherlands or Australia show more constraint, and generally are much more interesting.

Sunday, April 24, 2011

Spark! by John J. Ratey and Eric Hagerman

Homo Sapiens no longer needs to walk long distances, run, jump, or catch prey. Our bodies, however, still work best when we move. When we spend our days sitting, we get fat and... dumb.

"Spark" starts with a quote from Plato:
In order for man to succeed in life, God provided him with two means, education and physical activity. Not separately, one for the soul and the other for the body, but for the two together. With these two means, man can attain perfection.
How to summarize "Spark"? Exercise is good for your brain? Yes, but there is much more. Dr John Ratey, a psychiatrist and researcher, spent two years writing "Spark". He describes recent research that proves that physical exercise in many cases works as well, or even better than a pill. The book goes into details what happens in your body when you exercise. It looks at different forms of physical activity: walking, running, aerobics, karate, etc, and different areas of our well being: mental health, aging, menopause, and even cancer.

The benefits of staying active are clear and are proven. Steady exercise: walking, running is essential. Sprinting works differently and is beneficial too. Physical activity that makes the brain work: karate, tennis, and other small team games are important from a different perspective. Exercising with others is better than doing it alone.

My favorite citation comes from page 237: "[...] if you are not busy living, your body will be busy dying."

John Ratey's web page.

Sunday, April 10, 2011

DON'T PANIC - Nearly Everything is Better Than You Think

Cassandra Wilkinson did a lot of reading for this book. References at the end take 20 pages out of total 200. The references are a strong part of this book. This sentence on page 30:
Spending time in stimulating company has been shown to develop our neural pathways [...]
has lead me to A User's Guide to the Brain: Perception, Attention, and the Four Theaters of the Brain by John Ratey, which I need to read one day.

Cassandra gives many examples of fear-mongering and then cites research that shows the opposite. She discusses happiness, family, society, fertility rate, economy, globalisation, war on terror, fashion, politics and other everyday news topics. All in Australian and international context. 

The message stated in the title is clear and powerful: don't worry, this is not the end of world. When you live in fear you are proven to make wrong decisions. When you have faith in other people, progress is made.

Friday, March 11, 2011

The i Programming Language - Part 1 - The Concept

Here is my idea for a new programming language. The language is called "i" for Internet, or interactive. The main difference between i  (or IPL) and other languages of today is the dynamic, or even unpredictable nature of i programs. This is achieved by using two key features:

A program written in i, every time it runs, uses:
  1. Different data. Input data is provided by Internet APIs like google search, flickr, youtube, amazon. For example when the program needs a picture of a a car, it grabs it from one of the free repositories on the Internet. Possibly, it grabs a different picture every time it runs. When a program needs encyclopedic information, it gets an article from wikipedia. When it needs a definition of a word: it uses a free dictionary or google's "define: this", when it needs a word translated, it uses and so on. It can use paid services too. It all depends on what libraries are available. And here we come to point 2.
  2. Different algorithms. Algorithms can be provided by libraries or functions found on the Internet. The i runtime engine, if it cannot find a requested library or function locally, starts searching around, maybe looking in a few hinted or well known places, or maybe all over the Internet, again using google search.
It is possible to write functions, or libraries that can be executed by any i program that finds them at runtime. Like the Internet is more than just a collection of web sites, an i program is more than just a collection of functions.

To make the language universal, and quick to accept, it compiles to JavaScript bytecode or is read and executed by an interpreter written in JavaScript. The i program, and the i libraries can be hosted inside regular html web pages. That's how they can be discovered quickly. A regular web search finds them.

The execution flow looks like this:
  1. A user requests a web page from a web server. The web page contains an i program in a native format plus an i interpreter written in JavaScript. Or it contains an i program already converted to JavaScript.
  2. The program starts running on page load event or when the user clicks a button or some other way. The program gets data, finds and calls other i programs using AJAX calls to i runtime engine hosted on a web server within the same domain, which in turn calls various Internet APIs. Note: the primary runtime environment is the browser, but the runtime on the server is needed to get past same origin policy, to make the i interpreter smaller and simpler, and to provide standard i libraries. The program is effectively running inside the user's browser downloading data and pieces of i code as it goes. It can also run code written in any language, executed on web servers, exposed using REST. Details to be defined.
  3. An i program can run forever, and can run simultaneously on an unlimited number of computers by spawning itself from the browser to servers that accept i code for execution.

Wednesday, March 9, 2011

My ruby zoo

Ruby is fun. A lot of fun. It makes programmers smile.  It makes them try crazy things... and those crazy things work.

Thank you Yukihiro Matsumoto!

Here is a little game I wrote with my kids one Saturday afternoon maybe a year ago.
There is an animal.rb and a zoo.rb and there is myzoo.rb which runs all that. I ran it using IronRuby.

class Animal
  # create accessor methods for reading these properties 
  attr_reader :attractiveness, :upkeep, :name, :age, :dies_at, :cost_to_buy, :current_value, :dead
  MAX_UPKEEP = 100

  ADVERBS = ["Small", "Big", "Smelly", "Cutest", "Sweetest", "Greenish", "Killer", "Harmless", "Angry"]
  NOUNS = ["Croc", "Elephant", "Hippo", "Ant", "Bear", "Mollusk", "Octopus", "Snake", "Snail"]

  def initialize(name)
    @attractiveness = rand(MAX_ATTRACTIVENESS)
    @upkeep = rand(MAX_UPKEEP)
    @name = name
    @age = rand(MAX_AGE_WHEN_BUYING)
    @dies_at = @age + rand(MAX_YEARS_TO_LIVE_AFTER_BUYING)
    @cost_to_buy = rand(MAX_COST_TO_BUY)
    @dead = false

  def Animal.get
    name = ADVERBS[rand(ADVERBS.length)] + " " + NOUNS[rand(NOUNS.length)]  

  def make_older
    return if @dead
    if age == @dies_at
       @dead = true
       puts @name + " died of old age."
       @age += 1
       @attractiveness -= 1

  def show
    puts "Name: #{@name}"
    puts "Attractiveness: #{@attractiveness.to_s} max: #{MAX_ATTRACTIVENESS.to_s}"
    puts "Cost to buy: $#{@cost_to_buy.to_s} max: #{MAX_COST_TO_BUY.to_s}"
    puts "Upkeep per year: $#{@upkeep.to_s} max: #{MAX_UPKEEP.to_s}"
    puts "Age: #{@age.to_s} year(s). max: #{MAX_AGE_WHEN_BUYING.to_s}" 
    puts "Dies at: #{@dies_at.to_s} year(s). max: #{(MAX_AGE_WHEN_BUYING + MAX_YEARS_TO_LIVE_AFTER_BUYING).to_s}" 
end # class Animal

class Zoo
  # ticket price can be set directly
  attr_accessor :ticket_price 
  # other properties are set internally 
  attr_reader :overhead_cost, :seed_money, :animals, :upkeep, :year, :animals_bought, :guests, :revenue, :cash

  def initialize()
    @animals =
    @upkeep = 0
    @overhead_cost = 100
    @ticket_price = 10
    @guests = 0
    @revenue = 0
    @seed_money = 500
    @cash = @seed_money
    @year = 0

  def show
    puts "Animals: " + @animals.length.to_s
    puts "Upkeep last year: $" + @upkeep.to_s
    puts "Overhead cost: $" + @overhead_cost.to_s
    puts "Ticket price: $" + @ticket_price.to_s
    puts "Revenue last year: $" + @revenue.to_s
    puts "Guests last year: " + @guests.to_s
    puts "Cash: $" + @cash.to_s
    puts "Year: " + @year.to_s

  # This defines how we buy animals:
  def buy_animal(animal)
      @cash = @cash - animal.cost_to_buy
      puts "You now have: $" + @cash.to_s
      @animals.push animal

  def next_year
    @upkeep = 0
    @animals.each do |animal|

    @animals.delete_if do |animal| 

    @animals.each do |animal|
         @upkeep += animal.upkeep

    @guests = 0
    @animals.each do |animal|
        @guests += animal.attractiveness
    @guests = (@guests/Math.sqrt(@ticket_price)).to_i
    @revenue =  @guests * @ticket_price
    @cash += @revenue - @overhead_cost - @upkeep
    @year += 1

end #class Zoo

require "zoo.rb"
require "animal.rb"

SCORES_FILE = "scores.txt"

def show_hall_of_fame, CREATE_OR_APPEND_MODE) {}
  scores = IO.readlines(SCORES_FILE) 

  puts "Hall of fame: "
  puts " waiting for your name" if scores.length == 0
  puts scores if scores.length > 0

def update_hall_of_fame (cash, player), CREATE_OR_APPEND_MODE) {}
  scores = IO.readlines(SCORES_FILE) 
  scores[scores.length] = format("%10.10s %s", cash.to_s, player) 
  scores.sort!.reverse!, WRITE_MODE) {|f| f.write(scores) }

def show_menu
  puts "b = Buy Animals"
  puts "s = Sell Animals" 
  puts "p = Set Ticket Price" 
  puts "a = Show Animals" 
  puts "z = Show Zoo" 
  puts "n = Next Year" 
  puts "h = Hall of Fame" 
  puts "q = Quit"

puts "Welcome to MyZoo!"
puts "You manage it. Try to make as much money as you can in #{YEARS_TO_PLAY.to_s} years."

print "What's your name boss? "
player = gets

myzoo =

puts "You have in the bank: $" +

playing = true

while playing and myzoo.year <= YEARS_TO_PLAY do
  print "Enter command:"
  command = gets

  case command
    when "b\n"
      some_animal = Animal.get
      print "Do you want to buy this animal? (y/n) "
      answer = gets
      myzoo.buy_animal(some_animal) if answer == "y\n"
    when "s\n" 
      if myzoo.animals.length > 0
         puts "Your salesperson has been eaten by #{myzoo.animals[0].name}." 
         puts "There is no fauna in your zoo."

    when "p\n" 
      print "New ticket price: "
      answer = gets
      if answer.to_i > 0
         myzoo.ticket_price = answer.to_i  
         puts "Sorry, no free tickets this year." 

    when "a\n" 
        if myzoo.animals.length > 0 
           puts "Your animals: " 
           myzoo.animals.each do |animal|
           puts "Did you buy any? Are they still alive?"

    when "z\n"    

    when "n\n"

    when "h\n"

    when "q\n"
      print "Abandoning your enterprise? (y/n)"
      answer = gets
      if answer == "y\n" then 
         puts "Good-bye!"
         playing = false

update_hall_of_fame(, player) if > 0

Tuesday, March 8, 2011

"Marek Edelman. Życie. Po prostu." by Witold Bereś and Krzysztof Burnetko.

I have read this 500 page book in Polish. The English title is "Marek Edelman: Simply A Life". A 30 minute DVD is included with the book. It shows Edelman being interviewed by the authors for the book.

This book is for you if you are looking for a first hand account of what the relations between different groups of Jews and Poles were in pre-war Poland, during the war, and after.

This book tells the story of the first Warsaw uprising - the Ghetto uprising - as it was: without pathos. It is a shocking story, but told without big words or hatred.

This book also tells a more general story. This book is for you if you are looking for inspiration how to live your life. What is important.

A few quotes by Marek Edelman:
"In life, those who let others live, are right."
"In principle, life is most important. And if you live, then the most important thing is freedom. And then you give life for freedom. And then you don't know what is most important."
"I am a Polish Jew, but Ala [wife] and all Jews think that I am a disgusting polonophile, and that I have a character of a Pole. But I think that patriotism is disgusting. I would never say about myself that I am a patriot - I am a patriot of the idea of freedom everywhere."
And finally:
"In life, I like caviar and beautiful girls."

The Associate by John Grisham

Read by: Erik Singer

Another story from the world of lawyers. We meet Kyle McAvoy when he is a senior at Yale law school. He is about to graduate and start a career in public law, but someone sinister has other plans for him. What will Kyle do with his life? Will he follow his ideals or will he give in to the dark side?

Monday, March 7, 2011

Language Implementation Patterns by Terrence Parr

Rating: Lot's of information, but poorly presented.

Basic Patterns:
  • Mapping Grammars to Recursive-Descent Recognizers: convert formal language specification (grammar) into a parser.
  • LL(1) Recursive-Descent Lexer: break up character streams into tokens.
  • LL(1) Recursive-Descent Parser: make a parsing decision (choose parsing method) for the current (1) input symbol.
  • LL(k) Recursive-Descent Parser: make a parsing decision (choose parsing method) for up to k next input symbols.
  • "A language is just a set of valid sentences."
  • "To parse, then, is to conjure up a two-dimensional parse tree from a flat token sequence."

This book could have been much better. It suffers from the following problems:
  •  Code examples:
    • Incompleteness - critical functions are missing initially: code which uses match() starts on page 41, but match() implementation is shown on page 55 for the first time.
    • Names of variables and functions are cryptic/not clear and do not follow one convention: 
      • variable names: T, p, c, x, k, i, r, Integer memoI, int memo, FOLLOW_INT_in_point37, _save,
      • function names: LT(), LA(), isSpeculating(), alreadyParsedRule(), _list(), speculate_stat_alt1().
  • Critical terms are used without introduction.
  • Definitions seem chaotic/incomplete.
  • Concepts are introduced in chaotic order.
  • Some concepts seem to change meaning: current token becomes a lookahead token.
  • There is a lot of alternative terminology that is used without introducing it properly: here are my notes on  "lexer":  Lexer: a type of recognizer; aka scanner, aka lexical analyzer, aka tokenizer: reads a stream of characters and yields a stream of tokens aka input symbols, aka vocabulary symbols.

Software Creativity by Robert Glass

Rating: A critical look at formal methods as a solution to all.

By page 19 (and 13 pages of forewords) we learned that there are two opposite views of how software should be developed: disciplined and flexible, and that the author will in the end show us that the middle way is the best.

Author's theory about software practice includes these issues:
  • Discipline vs. flexibility
  • Formal methods vs. heuristics
  • Optimizing vs. satisficing (sic!)
  • Quantitative vs. qualitative
  • Process vs. product
  • Intellectual vs. clerical tasks

On page 268 there is a good list of what academic research should be focusing on, two of which seem especially worthy:
  • issues contrary to commercial interests,
  • unsolved problems.

I think that definition of standards with sample implementations might fall into the "contrary to commercial interests" category. This might prevent the "design by committee" problems that we see in CORBA and IATA CUSS standards.

Chapter 9 contains an interesting discussion of "fun" in software development. The author references a paper by Bruce Blum, who lists the fun/tedium ratio for different phases of SDLC:
  • "selling the concept" phase - pure problem solving/analysis phase: 100% fun - 0% tedium
  • writing down requirements: 50-50
  • top-level design: 40-60
  • detailed design: 33-67
  • programming: 75-25
  • testing: 33-67
  • maintenance: 0-100

Chapter 9.3 mentions another interesting idea for creating projects with higher ratio of fun - the "incremental consensus" technique by Jerry Weinberg: begin with 2 people who want to work in a mutually pleasing manner and succeed on a project, then grow the team in increments of 1 and only when the candidate gets everyone's acceptance.

Chapter 13 lists ideas on how organizations can become more creative:
  • support open sharing of information
  • support risk-taking behaviors
  • create group diversity
  • create highly participative culture
  • create "slack resources"

Chapter 14 lists traits of creative people.

Chapter 15 shows that computer tools can decrease creativity in problem solving.

Chapter 16 explains creativity paradoxes:
  • The more you know about the problem domain, the less creative your solutions are.
  • To come up with creative solutions, you must know how others solved it.

Chapter 17 shows that software life cycle is just an implementation of a universal problem solving algorithm:
  • Identify a problem.
  • Define the requirements of the problem.
  • Design a solution to the problem.
  • Implement the design.
  • Test the implementation.
  • Use the implemented product.

What I am missing in this book is the word "pragmatic". It is a simple, elegant, and "to the point" summary of the approach that Robert L. Glass postulates to use for software development.

Rapid Development by Steve McConnell

Rating: Instruction manual for software projects.

Chapter 7 - Lifecycle Planning - has a surprise for those who think that "Agile" and "SCRUM" are new revolutionary concepts. This book was written in 1996 and the Evolutionary Prototyping, Staged Delivery, Design-to-Schedule, and Evolutionary Delivery processes described there look eerily familiar to us.

There is a very interesting table on page 156: Lifecycle Model Strengths and Weaknesses. The Spiral model is a clear winner.

Chapter 9 - Scheduling - explains what the estimated completion date really is. "Developers typically estimate 20 to 30 percent lower than their actual effort. Merely using their normal estimates puts the chance of completing on time below 50%".

Chapter 11 - Motivation - has interesting insights about developers and managers. For example: "Compared to the general population, developers are much more motivated by possibility of growth, personal life, opportunity for technical supervision, and interpersonal relations with their peers. Developers are much less motivated by status, interpersonal relationships with subordinates, responsibility, and recognition."

Percentage of computer professionals who have a preference for:

  • introverted (I) over extroverted (E): 58%... I = interested in ideas rather than people and things,
  • thinking (T) over feeling (F): 80%... T = logical, objective decisions,
  • judging (J) over perceiving (P): 66%... J = live in a planned, orderly way.

Chapter 43 - Voluntary Overtime - shows in a Machiavellian way how to trick developers into producing more without compensation. It's tricky, but it can be done. Other ways DO NOT work. Involuntary or excessive overtime decreases overall productivity. "Trying to motivate developers can be like trying to push on a rope - you'd be better off pulling on the other end."

Key Lessons:

  • Software development can be optimized for schedule, quality, performance, maintainability, usability, cost. Pick one or make trade-offs.
  • To get software on time you must:
    • not make classic mistakes,
    • follow software development fundamentals,
    • manage risk,
    • use schedule-oriented practices.

Rapid Development complements Code Complete. It gives team leads and managers knowledge with which they can deliver software projects on time.

Applying UML & Patterns 3rd Edition by Craig Larman

Rating: Too many words. Too little essence. Messy. Academic.

This 700 page book could be easily re-edited to fit 400 pages or less. There are very few original ideas here. There is a lot of repetition, obvious statements, outside of topic statements, defensive statements, and meta-content. There was one bit of wee humor in the first 240 pages, but I did not write it down immediately, and now I cannot find it. :-(

This book looks like an attempt at jumping on the agile development bandwagon, by someone who preached for ages a complex, UML and roles driven, approach to software development, and now is very apologetic about it.

Chapter 22 tells us that UML is used as a sketch, as a blueprint, and very rarely as a programming language.
Chapter 22 contains also this breaking piece of news: '''developers consistently report that UML tools seem to "get in the way" more than help''' - page 396.

The CUPPS standard defines "log in" and "log on" as 2 different operations. In the same fashion this book on page 594 defines "fault", "error", and "failure" as 3 different terms. Which normal person is going to remember what is what?

Conceptual Blockbusting: A Guide to Better Ideas by James Adams

Rating: Boring, except for one or two puzzles.

This book shows you how to be more creative by discovering where your blocks are and how to break them. Your thinking process may be constrained by blocks originating in: perception, emotion, culture, environment, intellect, expressiveness.


  • using alternate (to verbal) thinking languages: mathematical, sensory (visual, etc.).
  • questioning attitude
  • finding the core problem
  • making lists
  • combining alternate attributes
  • trying manipulative verbs
  • getting input from other people, especially coming from other disciplines, cultures, environments

Method of loci (locations in Latin): associate physical locations with items that you want to remember. Take a walk in your head to recall the items.

Programming Pearls 2nd Edition by Jon Bentley

Rating: Devilishly difficult sometimes, but valuable. I will read it again one day.

  • Principles from Column 1: 
    • ''The Right Problem''', 
    • The Bitmap Data Structure, 
    • Multiple-Pass Algorithms, 
    • A Time-Space Tradeoff and One That Isn't, 
    • A Simple Design, 
    • Stages of Program Design.
  • "don't write a big program when a small one will do" - page  29
  • "the more general program may be easier to solve"
  • "back of the envelope" calculations - page 67
  • Rule of 72
  • Little's Law: "The average number of things in the system is the product of the average rate at which things leave the system and the average time each one spends in the system." - page 73
  • save state to avoid re-computation - page 84
  • pre-process information into data structures, divide and conquer, scanning, cumulative
  • Good programmers keep efficiency in context: it is just one of many problems in software, but it is sometimes very important. - p.87

  • If we assume that we have a "reverse" function, why not assume that we have a rotate function, and be done with it? - Column 2
  • Variables in examples have almost always 1 letter names: m, n, i, x, l, t.

Bottom Line:

What makes this book difficult to read is the mathematical approach.

The problems are not common - almost nobody is writing their own search algorithms, or random number generators nowadays - but they provide insight into how things work. For example why it is a good idea to tell the hash class at initialization the approximate number of elements.

This book is a hard one. I feel like I need to read it again, do some exercises, and feed the Mnemosyne.

Code Complete 2 by Steve McConnell

Rating: The Bible of Programming. Every developer can learn a few things from it
and have an occasional laugh.

  • heuristics vs algorithms
  • metaphors for making software: 
    • penmanship: writing code, 
    • farming: growing a system, 
    • oyster farming: system accretion, 
    • construction: building software.
  • good practices differ for different kinds of software projects: business systems, mission-critical systems, embedded life-critical systems - page 31
  • typical architectural components: program organization, major classes, data design, business rules, user interface design, resource management, security, performance, scalability, interoperability, internationalization/localization, input/output, error processing, fault tolerance, architectural feasibility, over-engineering, buy vs. build decisions, reuse decisions, change strategy, general architecture quality.
  • technology wave - page 66
  • programming into a language (good) vs programming in a language (bad) - page 68
  • a "wicked" problem - one that can be clearly defined only by attempting to solve at least part of it - page 74
  • accidental and essential difficulties - page 77
  • desirable characteristics of a design: 
    • minimal complexity, 
    • ease of maintenance, 
    • loose coupling, 
    • extensibility, 
    • re-usability, 
    • high fan-in: having a high number of classes that use a given class, 
    • low-to-medium fan-out: having a given class use a low-to-medium number of other classes  (high cohesion), 
    • portability, 
    • leanness: designing the system so that it has no extra parts, 
    • stratification - design the system so you view it at one level without dipping into other levels,
    • standard techniques - page 81
  • design building blocks: 
    • major heuristics: find real-world objects, form consistent abstractions, encapsulate implementation details, inherit - when it simplifies the design, hide secrets, identify areas likely to change, keep coupling loose, look for common design patterns
    • minor heuristics: aim for strong cohesion, build hierarchies, formalize class contracts, assign responsibilities, design for test, avoid failure, choose binding time consciously, make central points of control, consider using brute force, draw a diagram, keep your design modular
  • design practices: iterate, divide and conquer, top-down and bottom-up approaches, experimental prototyping, collaborative design
  • Abstract Data Type (ADT) - page 126
  • semantic encapsulation - page 141
  • Liskov Substitution Principle (LSP) - you shouldn't inherit from a base class unless the derived class truly "is a" more specific version of the base class - page 144
  • "mixins" - classes, usually abstract, meant to be inherited from in multiple inheritance - page 149
  • shallow copies (reference objects) vs deep copies (value objects) - page 152
  • "gold-plating" - creation of functionality that isn't required and that unnecessarily adds complexity - page 154
  • "god class" - a class not to create - page 155
  • types of acceptable cohesion in a routine - page 168:
    • functional - performs one and only one operation - the ideal,
    • sequential - contains operations on shared data that must be performed in a specific order,
    • communicational - operations share data, but are otherwise unrelated,
    • temporal  - contains operations that are done at the same time.
  • types of unacceptable cohesion in a routine - page 170:
    • procedural - operations performed in order matching UI,
    • logical - performs one of contained operations based on an input flag,
    • coincidental - no relationship between operations.
  • defensive programming
  • assertions - "Error handling typically checks for bad input data; assertions check for bugs in the code." - page 191, but "For highly robust code, assert and then handle the error anyway" - page 193
  • preconditions
  • postconditions
  • robustness vs. correctness - page 197
  • barricade - page 203
  • debugging aids - page 205
  • PPP - pseudocode programming process - page 215
  • Principle of Proximity - keep related actions together - page 242
  • window of vulnerability, variable span - average number of statements between variable references, variable live time - max number of statements between references - page 245
  • hybrid coupling - two variables in one - page 256
  • the telephone test - "[...] if you can't read your code to someone over the phone, rename your variables to be more distinctive [...]" - page 283
  • write-time convenience vs. read-time convenience - page 285
  • dog-tag - a field added for error checking - page 326
  • tramp data - data passed to a routine only to be passed to another routine - page 338
  • guard clause - code that exits a routine early if it is not ok to proceed, to avoid deep nesting - page 392
  • safety counter - a counter variable that prevents infinite loops - page 396 and earlier
  • cyclic recursion - A calls B, B calls C, C calls A - page 396
  • table-driven approach - lookup information in a table rather than using logical statements - page 411
  • indexed access tables - page 425
  • stair-step access tables - page 426
  • DeMorgan's Theorems - use to simplify boolean tests - page 436
  • structured programming - you can build any program out of a combination of sequences, selections, and iterations - page 454
  • McCabe's cyclomatic complexity metric - the sum of decision points in a routine - 10+ is possibly too complex - page 458
  • quality gates - page 467
  • collaborative construction - page 480
  • formal inspections - page 485
  • walk-through, code reading, dog-and-pony show - page 492
  • black-box/white-box testing - page 500
  • structured basis testing - page 507
  • data flow testing - page 509
  • equivalence partitioning, error guessing, boundary analysis, compound boundaries, classes of bad/good data- from page 512
  • system perturbers - page 527
  • confessional debugging - page 547
  • brute-force debugging - page 548
  • voodoo programming - page 553
  • psychological distance - page 556
  • code-tuning: loops: unswitching, jamming, unrolling, sentinel values - page 616
  • strength reduction - page 630
  • phased vs incremental integration - page 691
  • top-down vs bottom up integration - page 694
  • integration types: sandwich, risk-oriented, feature-oriented, T-shaped - page 698
  • Fundamental Theorem of Formatting - page 732

Bottom line:

  • "Specifying requirements adequately is a key to project success [...]" page 39
  • "Once you understand that all technical goals in software are secondary to managing complexity, many design considerations become straightforward." - page 79
  • "Design is heuristic. Dogmatic adherence to any single methodology hurts creativity and hurts your programs." - page 123
  • "If a routine has bad cohesion, it's better to put effort into a rewrite to have better cohesion than investing in a pinpoint diagnosis of the problem." - page 169
  • "The name of a routine is an indication of its quality." - page 186
  • Define quality goals - page 469
  • "[...] effective software-quality program must include a combination of techniques [...]" - page 473
  • "[...] inspections quickly brought all the developers up to the level of the best developers [...]" - page 482
  • "The first priority of visual layout is to illuminate the logical organization of the code." - page 775.
  • "Holy Grail of legibility: self-documenting code. [...] In well-written code, comments are the icing on the readability cake." - page 779
  • Good comments: "[...] information that can't be expressed in code, intent comments, and summary comments." - page 788
  • "If you're figuring out code instead of reading it, it's too complicated. If it's hard, it's wrong. Make it simpler." - page 849
  • "A blanket attempt to avoid mistakes is the biggest mistake of all." - page 852

:-) Funny bits:

  • "In programming, if your requirements are contaminated, they contaminate the architecture, and the architecture in turn contaminates construction. This leads to '''grumpy, malnourished programmers''' and radioactive, polluted software that's riddled with defects."
  • "It's as if you were a contractor called to work on a house. Your customer says, "What will it cost to do the work?" You reasonably ask, "What do you want me to do?" Your customer says, "I can't tell you, but how much will it cost?" You '''reasonably''' thank the customer for wasting your time and go home."
  • Comparing productivity of higher and lower level languages: "You save time when you don't need to have '''an awards ceremony''' every time a C statement does what it's supposed to." - page 62
  • "You'd probably want to '''tar and feather''' a teacher who gave you a programming assignment, then changed the assignment as soon as you finished the design, and then changed it again just a s you were to turn in the completed program. But the very process in an everyday reality in professional programming." - page 75
  • "[...] the road to programming hell is paved with global variables [...]" - page 95
  • "A vague, wishy-washy [routine] name is like a politician on the campaign trail. It sounds as if it's saying something, but when you take a hard look, you can't figure out what it means." - page 222
  • "[About memory initialization] Alternatively, Brian Kernighan and Rob Pike suggest using the constant 0xDEADBEEF as a memory filler that's easy to recognize in a debugger [...]" - page 244
  • "You can't give a variable a name the way you give a dog a name - because it's cute or it has a good sound." - page 259
  • The optimum length for a name seems to be somewhere between the lengths of x and maximumNumberOfPointsInModernOlympics." - page 262
  • "It's OK to figure out murder mysteries, but you shouldn't need to figure out code." - page 267
  • "FALSE [...] would be a bad abbreviation for 'Fig and Almond Season'" - page 285
  • "By the time structured programming came and went, the term 'structured' had been applied to every software-development activity, including structured analysis, structured design, and '''structured goofing off'''." - page 454
  • "[...] compilers are dissembling little rascals, [...]" - page 549
  • "Some compilers get so excited after detecting the first error that they become giddy and overconfident; they prattle on with dozens of error messages that don't mean anything." - page 550
  • "Code as if whoever maintains your program is a violent psychopath who knows where you live." - page 777

Interesting observations:

  •  7 +/-2 is a number of discrete items a person can remember while performing other tasks. If a class contains more than about seven data members, consider splitting it into smaller classes. - page 143
  •  "A good way to think of assertions is as executable documentation [...]" - page 191
  •  "[...] code reviews were several times as cost-effective as testing [...]" - page 473


  • The Java Singleton example on page 151 is not correct, because it does not close the class for inheritance
  • The "Avoid classes named after verbs" recommendation on page 155 does not mention the Strategy pattern, where naming your behavior classes after verbs may be desired
  • The Visual Basic example of a centralized exception reporter on page 202 does not follow the rules of defensive programming (no parameter validation) and the law of Demeter ("thisException.TargetSite.Name"). ReportException() may itself throw an exception in some cases.
  • Some abbreviation guidelines on page 282, like "Remove all nonleading vowels", "Keep the most noticable sound in each syllable" make the code difficult to read for non-native English speakers.
  • The concept of coding into a language may be misused to make a C# program look and act like a COBOL program.
  • The author mentions C++, and Java often, but skips C# which has the same features - page 439
  • Writing numeric expressions in number-line order makes them difficult to read: you have to start in the middle of the line and read to the left and right at the same time. It looks good when you draw it, but it is awkward to read - page 440