Monday, 27 January 2014

Book Review: Frankenstein

Frankenstein

Although the writing is at times awkward, Shelley explores a number of interesting ideas in this book. 

Dr Frankenstein creates a monster. More like a meat puzzle than the relatively tidy later depictions. One question raised is what is life and what is it to be human? The Monster in fact is superhuman - stronger, smarter and faster than it's creator.

The Monster is driven toward murder and psychopathy by the hatred showed by the human race.

Worth reading, although there does seem to be a good deal of padding at the beginning.

Title: Frankenstein
Author: Mary Shelley
Rating: 4/5

Saturday, 4 January 2014

Book Review - 2001: A Space Odyssey and Catch 22

2001: A Space Odyssey

Who would have thought that it was possible to get stranger than the movie of 2001: A Space Odyssey. Well buckle up because this book does it.

The premise of this book is that some form of alien race has left a crystal block which is capable of giving the spark of knowledge to humans.

A major theme of the book is questioning what is life and what is a mind - particularly with HAL the homicidal computer.

Title: 2001: A Space Odyssey
Author: Arthur C. Clarke
Rating: 4/5

Catch 22

This novel was the origin of the term "catch 22" relating to paradoxes. It details the descent into madness of a bomber pilot, Yossarian. The story gives a sense of being trapped, the insanity of war and the reader shares the state of confusion which Yossarian finds himself in.

The concept of catch 22 centres around the paradox that to be found unfit to fly due to insanity the pilot must request to be sent home. However requesting to be sent home - away from dangerous missions - is a sign of sanity. Thus it is not actually possible to be sent home.

An interesting literary device which the author used was to write some text that was so over the top that it throws the reader out of their imagination. Normally this is a very bad thing for writing or movies (Matrix 2 freeway seen for example) and is normally a sign of poor writing rather than a technique.

In Catch 22 however this device is used with a certain rhythm and the confusion of the reader being thrown out of the book helps the reader to share the confusion that Yossarian is facing. As the book progresses Yossarian begins to hallucinate and become paranoid.

He is at war though - so people really are trying to kill him.

An excellent novel which I thoroughly enjoyed.

Title: Catch 22
Author: Joseph Heller
Rating: 5/5

Wednesday, 4 December 2013

Python: The Need For Speed

Python is a great language, I use it practically every day. But Python has a dirty little secret. It is hideously slow.

I have first hand experience of Python just being too slow. In a real world project I found that the best Python implementation ran in 4 seconds and an unoptimised Java version ran in 128ms: a 30 fold improvement.

That comparison is a little unfair - Java is a compiled statically typed language after all. Unfortunately compared to Javascript on the v8 engine Python speed still sucks. The median result was that Python programmes took 12 times longer to run, with a maximum of 50 times slower.

Now some other Pythonistas have mounted the following arguments:

  1. Most of the time it doesn't matter
  2. It is fast enough for scientific calculations using scipy and numpy
  3. Computation intensive tasks should be re-written as a C plugin
  4. Use pypy
The first argument is usually correct. Does it really matter if a programme runs in 1s instead of 1ms? No. There are a minority of cases where performance does matter. It is in this case that Python is not acceptable.

Points 2 and 3 are really the same. Scipi and numpi are written in C, not native Python. The answer to "how do you write a fast Python programme?" seems to be "write it in C". This sounds like the old joke about the tourist wanting to find their way to Dublin with the response being "If I were you I wouldn't start from here". If I have to write a module in C for a performance critical app, why not just write the entire app in a faster language such as Java or C++

Point 4 is cited by a number of Pythonistas - but most C modules are incompatible with pypy and pypy currently has poor Python 3 support. So we are told to write C modules in responses 2 and 3 but then that paints us into a corner with using pypy.

There is another issue with having multiple interpreters - Python has limited resources which are spread between CPython, pypy, Jython and IronPython.

Python needs to merge CPython and pypy - providing a JIT reference implementation and preventing fragmentation in the Python community. This will significantly reduce the number of cases where a C module needs to be written.

I love Python and it has only once been too slow for my needs. But Van Rossum's statement that "It is usually much more effective to take that one piece and replace that one function or module with a little bit of code you wrote in C or C++..." is a cop-out. Python can do better - pypy is already doing better. 

Python should adopt pypy as the default implementation, so Python can achieve good speeds without having to call out to C.

Friday, 28 June 2013

ABC iview Isn't Working on Android

On my HTC sensation running 4.0 I had to do Menu->Settings->Advanced->Enable Flash and plug-ins->On demand [Always on would probably be ok too]

I also manually updated to the latest flash player but I don't know if that helped

Update: a project has been released which gets i-view working on Android: https://play.google.com/store/apps/details?id=com.github.aview.app&hl=en

Friday, 31 May 2013

Qt4 and Boost On Windows


Instructions

The Qt4 binary on Windows conflicts with the boost pro binaries. The key problem is the -Zc:wchar_t compiler option

I used Microsoft Visual C++ 2010 Express

Download the source code


In "mkspecs\win32-msvc2010\qmake.conf" change:
QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t-
to
QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t

Then configure (is an .exe), nmake release. Done! Then add the includes and library into your own application project.

Helpful Links



Monday, 22 April 2013

What I Have Learned About Unit Testing

I am just an ordinary programmer trying to do his job. I do not sacrifice to the altar of Test Driven Development or consider myself an uber-programmer. I am just trying to avoid being called at 3am.

I took over the software itself from another programmer. His coding was quite nice with only one or two minor oddities which I am happy to overlook. However the unit tests that were available did not consist of much and were not documented (which is fair enough).

The software has had about 20 minutes downtime in 10 years so the quality expectations were very high. I assumed I would make mistakes and so took multiple steps to try to reduce the risk. This article concentrates on the testing step.

Use the Tools You Get For Free

I used to write an Apache module in C++ which handled about $800 million a year in advertising clicks at its peak, called the clickserver.

One of the most amazing tools for C++ is valgrind, specifically memcheck. It is vital that C++ software be run through valgrind memcheck with representative data. Yes valgrind does vomit up thousands of references to the STL string library which is extremely annoying. The most important thing to pay attention to, in my experience, is uninitialised variables. Uninitialised will almost certainly cause logic errors in your code. Rather than memory leaks which are serious but not as serious as logic errors.

Play It Again Sam

One of the most successful strategies I used when developing the clickserver was to replay real world interactions from real visitors. This made it easy to find any regression issues with the new software.

I would frequently catch one or two major bugs: both regression and in the new features.

The previous programmer wrote a script to replay the log but the difference tool just used diff, which ignored the subtleties of the log format: it should always find a difference (e.g. timestamp). I wrote a more sophisticated tool which would diff the log files and allow elimination of false positives.

There were a few challenges with the replay scenario: environment and false positives.

The output of the clickserver (redirect location, log entry and outgoing cookies) was determined by the input URL, incoming cookies, cached data from the database and configuration. All four inputs must be identical to the original.

The input URL and incoming cookies can be reconstructed from the Apache log, with care to adjust timestamps that were contained in the inputs.

Fortunately the database caches were in file form and were archived. Files were used in case the database went offline and could easily be rolled back to an archive if things were messed up enough. Fortunately that never happened.

The false positives were another challenge. The issue is that bugs are fixed and new features are added in the new software. This will mean that there are differences that make sense. Initially I added an option to my log difference tool to ignore differences in various fields.

The problem is that I only want to ignore various fields if it is definitely a bug fix or new feature. To achieve that I added the rhino engine (ScriptEngine) that is built into Java to allow a more nuanced elimination of false positives. Performance was a real challenge using ScriptEngine. I eventually split the contents of the ignore script into two parts: one function returned a list of fields to ignore (for example completely new fields or those that changed every time) and one did a one-by-one analysis on each result that was a positive match. I did not design the script system to be able to override false negatives.

My Eyes Are Glazing Over...

As anyone who has done any form of in-depth testing can attest to, having too much information to check can cause one's brain to go into neutral. Particularly where we are looking for an error in a thousand or a hundred thousand entries.

Having a closed loop unit test is critical in that regard. An automated unit test should require no human intervention. It sounds obvious but many fall into the trap of creating a bunch of stimuli that a human has to go back to check.

A human should only be involved in filtering out false positives and debugging problems. Of course nothing can be perfect.

Closed Loop Automated Testing

In addition to the log difference utility I also wrote a suite of unit tests. Athough they simply used the interfaces presented by the software (http and log file) and did not test each class directly, which could be considered "functional testing", it used a low-level white box approach which should qualify as "unit testing". I used my knowledge of the internals of the software to create tests which should test the difficult parts of the software.

The tests were written in pyunit (unittest2). The tests were built up from a number of sources:
  1. the (undocumented) unit tests that had been present before
  2. use cases for visitors. Including what the visitor should do and what the visitor can do
  3. protocol tests: both following our protocols, following our protocols in edge cases and breaking our protocols
  4. bugs (and their fixes)
  5. new features
When I initially started the test and documentation project I made a huge spreadsheet with a number of test ideas from all these sources. I did the testing and documentation in unison because I kept finding that a number of "bugs" were not bugs - they were compromises that were not documented anywhere or misunderstandings.

Furthermore writing documentation shook out a number of inconsistencies and misunderstandings. I will go into further detail later.

I wrote a number of support classes, including a python implementation of tail. The end result ran in a few seconds, which was important because I wanted to be able to run it frequently. When the tests were slower I ran them less frequently.

Testing And Documentation?

Fortunately my former employer was forward thinking enough to allow me to do a testing project. I also included documentation in this for two good reasons. Firstly it was something else that needed to be done.

More importantly documentation and testing are intertwined. What is the correct behaviour? What if there are conflicts between what makes sense as "correct" behaviour in two different instances? I once heard that generally each software feature is trivial, it is the interactions between those features that generates complexity.

Furthermore in my experience good documentation improves a design. Having requirements, design, technical documentation or user documentation that has condition upon condition is usually a code smell for bad design. It requires users, programmers and application support hold more information in their minds.

Some people argue that the code is the documentation. If that is the case then the code by definition cannot have any bugs because it is being tested against itself. Furthermore less technical readers cannot read code. Even technical documentation may be read by application support, testers or sysadmins.

Documentation is required to describe a "contract" that the software will adhere to. The protocols and business requirements also form a "contract" that must be included. These contracts are then used in testing. These contracts are not enough to completely describe the software. I am not an advocate of design by contract (I will write about this in another post) but I am happy to pinch an idea here and there.

So documentation gives you something to test against.

The Future: Statistical Methods

Just before I left my last work I was investigating using statistical methods for monitoring new software which was deployed.

I started using Student's t-test but found that our data was too noisy to get a decent separation.

We knew anecdotally that our data was affected by a number of factors: local time of day, day of the week, day of the month, day of the year, client expenditure and many others.

Thus a multivariate analysis would have been likely to be helpful but I didn't have a chance to try it.

Conclusion

Using these steps, along with other quality assurance measures, helped keep the clickserver reliable with only a small number of bugs making it into production.

Sunday, 21 April 2013

I Will Fix Your Computer If...

Most professions have a concept of doing pro-bono work. Programming is an awesome job where we get to sit in the office all day. So we should give something back to the community. However we need some ground rules to make sure our time is not drained on a single job.

Computer

  1. Licence:
    1. Does it have a valid Windows licence?
    2. Will you buy a valid Windows licence?
    3. Can I install Ubuntu?
    4. Sorry can't help!
  2. Is it a hardware problem?
    1. A disk drive, RAM or RTC battery?
    2. Are you willing to donate it to be refurbished and given to someone?
    3. Sorry, can't help!
  3. Reformatting - the Windows disc
    1. I will take a backup
    2. Do you have the OS disks?
    3. Do you have a recovery partition?
    4. Have you not deleted the recovery partition?
    5. Will you buy a Windows disc?
    6. Sorry can't help!
  4. Re-installation - other software
    1. Do you have a valid license and disc / legit download?
    2. Will you buy it?
    3. Sorry can't help! (Warez is a PITA)
  5. Crapware / Warez
    1. Is this the second time?
    2. Can I restrict administrator rights?
    3. Can I install Ubuntu?
    4. Sorry can't help!

 Network

  1. Are basic settings correct?
  2. Is it a wireless problem?
    1. Is the modem / router wireless N?
    2. Replace the modem / router
  3. Does replacing the modem help?