Wednesday, 21 August 2013

North Brittany 2013

We booked a very last minute trip to north Brittany, to two camp sites just a few hours out of St Malo.

Saturday 27th July

Arrived just in time for ferry, fifteen minutes to spare, too close for comfort really. Great to have a cabin, had a meal and bought map etc. All slept well.

Sunday 28th July

Drove from St Malo to St Cast-le-Guildo. Drove straight to the Seymour's house, though it has been many years since I was last there.

Had a lovely walk along the beach, writing in the sand, collecting cuttle fish and Flora found two euros.

We split up and I ended up buying a coffee whilst Ellie used a loo, and spilt the whole cup in my lap, not best pleased.

We drove on to Camping le Cap Horn, where we were met with enthusiasm and great cheerfulness, which lasted the whole stay.

Our mobilhome had a covered porch with a great view over the bay. It was new this season, very clean and completely plastique!

Monday 29th July

We visited the E Leclerc at Paimpol for essentials. I spotted some cast iron crocottes, which we bought later. Bought Flora a digital watch.

Ruth knew she wanted to go to the Isle de Bréhat, so we went for a quick trip. Ellie bought the first of two thermometers. I caught eight fish from one tiny rock pool.

Tuesday 30th July

We went to an outdoor, tidal swimming pool.

Wednesday 31st July

On the way to a beach we stopped at a café

When we got to the beach

Flora and I launched the barge and coracle.

Thursday 1st August

Hung around.

Friday 2nd August

Ruth and Ellie walked to Abbaye de Beauport, Flora and I drove, via the Intermarche, where we bought some dolls house carpet.

The Abbaye is the start (km 0) of the pilgrimage to Santiago de Compostela.

Saturday 3rd August

We went for a boat trip around the Île de Beréhat, ending on the Île. We rented bikes and cycled around the whole island. We ate at a café on the main square. What a lovely place.

Our first stop was a tide mill.

We cycled all over both islands, spotting some beautiful cattle.

Sunday 4th August

Monday 5th August

Once packed and wished on our way we stopped at the Free Sculpture of Kito.

Bought some Cidre de Paimpol from the Carrefour to take home.

Stopped and horrified ourselves, at a travelling circus.

Arrived at Le Vieux Moulin Camping, Erquy.

Tuesday 6th Augst

Wednesday 7th August

Thursday 8th August

Ruth and the girls cleared out, for swim, whilst I had a 'phone interview with BlinkBox Music.

Went to Les Médievales de Fort La Latte.

Walked down to the beach at LanRuen, high tide but still very nice, through lovely woods.

Friday 9th August

Heard that BlinkBox did want to see me face to face, good end to the holiday.

Went to Pleneuf Val Andreé and had lunch at Plein des Sens. Then popped into a pottery owned by the café owners's mum.

Went down to the great beach at LanRuen, down from the camp site. It was low tide, there were fantastic rocks, a shoal of whitebait stranded in a large rock pool. We swam in the water, which was warm and a little wavy. We were sad to leave to pack up the mobilhome.

Saturday 10th August

Left the campsite at 8.20, though we had aimed for eight. No problems with the journey, arrived with fifteen minutes to spare.

Wednesday, 14 August 2013

Reimplementing Length Unit Converter in Java

Back in April I did a programming exercise in Python, which I really enjoyed and resulted in PyCLU and its Jenkins node, I was slightly sorry not to set up the Jenkins node earlier in the process, so the coverage graphs do not start at zero.

Today I received the same exercise with the option of implementing in Python or Java, so I have decided to reimplement in Java, rather than reuse my python implementation.

Setup

Following Project Initiation Recipe

Choose short name

JCLU

Choose stack

This will be a pure java command line application. It will be built using Maven on OpenJDK 7, with version compatibility set to 1.6, this was initially 1.4, but revised in the light of use of annotations within the testing code. It would be possible to use 1.4 in the artefact code and 1.6 within the testing code, should that become a requirement.

Create Repo

The only decision is public or private. It will be a git repo: here.

Choose CI

My Jenkins.

Setup dev machine

My dev machine has been set up according to this Ubuntu Setup Recipe.

Checkout and create Maven project from archetype

Now we have a buildable artefact.

Setup on Jenkins

Nice and early on, so that we can see test coverage evolve. Here

Diversion to reimplement RDD in Java

In the Python implementation I added an iteration of Requirements Driven Development (RDD), a utility born out of the audit driven culture of the NHS.

Annotating each test with which requirements it addresses enables a tighter coupling between requirements and tests.

RDD fits into the evolution of Agile programming by analogy with one of the justifications for Test Driven Development:

Why are you writing code?
To make a test pass
How do you know when to stop?
When all tests pass
The motivation behind RDD similarly:
Why are you writing that test?
To satisfy requirement ref X
How do you know when to stop?
When all requirements are tested

Another motivation, and tie-in with general Agile principles, is that it ties documentation to the code: the requirements grow when new tests are written as unforeseen requirements surface.

In PyCLU I used annotations, this should be possible in java (I have not written a java annotation before).

The idea is that a dated Requirements Verification Document will be produced by running the tests, that the tests will fail if there is an unmet requirement and the document can be published by Jenkins: here.

Ready to start

Quite a lot of work just to get to the starting line!

Translated PyCLU into java, adding only one test, that the wrong number of arguments throws an exception and that the specified input produces the specified output. This showed the slight differences in the specification: JCLU does not need to output the full name of the unit, does not accept multiple units eg 1 yd 3 in and does not need to add units. Removed unspecified code. This achieves 100% code coverage.

Now to test the requirements!

Reintroduce equals() and hashCode() for testing.

Convert all relevant tests from PyCLU; add tests for unused but needed hashCode() and equals().

Add tests for units not in PyCLU.

Review and submit!

Tuesday, 16 July 2013

Adding a library to java library path in Ubuntu

To enable a Java Native Interface (JNI) access to a non-java library, such as BerkeleyDB, then the library needs to be on the library path.

The simple answer given by Oracle and others is to run the command:

java -Djava.library.path=/usr/local/BerkelyDB.5.1/lib MyClass

That is a pain and difficult to ensure happens for all invocations of java.

It would be nice to use Ubuntu's ldconfig, but this is ignored by java! Java will however load from an environment variable LD_LIBRARY_PATH.

A sensible thing to do would be to place this variable in a system wide config, as it is a pain to add to every invocation of java, however due to supposed security issues this environment variable cannot be set in the normal places (/etc/environment, /etc/profile.d/) as it is deliberately nulled if you do set it!.

Sadly the only way is to add the following to the .bashrc of every user which will use your library (root, jenkins, jetty and yourself)

export LD_LIBRARY_PATH=/usr/local/BerkeleyDB.5.1/lib

Wednesday, 12 June 2013

Exploring the times tables with Haskell

Ellie couldn't sleep and had noticed that the digits of the 8 times table decline, in the way that the digits of the nine times table always add to nine.

Explore in Haskell

We will need a generator for a times table series

times n = [n * x | x <- [1..]]

gives:

*Main> times 3
[3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312,315,318,321,324,327,330,333,336,339,342,345,348,351,354,357,360,363,366,369,372,375,378,381,384,387,390,393,396,399,402,405,408,411,414,417,420,423,426,429,432,435,438,441,444,447,450,453,456,459,462,465,468,471,474,477,480,483,486,489,492,495,498,501,504,507,510,513,516,519,522,525,528,531,534,537,540,543,546,549,552,555,558,561,564,567,570,573,576,579,582,585,588,591,594,597,600,603,606,609,612,615,618,621,624,627,630,633,636,639,642,645,648,651,654,657,660,663,666,669,672,675,678,681,684,687,690,693,696,699,702,705,708,711,714,717,720,723,726,729,732,735,738,741,744,747,750,753,756,759,762,765,768,771,774,777,780,783,786,789,792,795,798,801,804,807,810,813,816,819,822,825,828,831,834,837,840,843,846,849,852,855,858,861,864,867,870,873,876,879,882,885,888,891,894,897,900,903,906,909,912,915,918....

just the first 12

take 12 $ times 3

gives

[3,6,9,12,15,18,21,24,27,30,33,36]

We want each number as a list of its digits:

listdigits n = if n < 10 then [n] else (listdigits (n `div` 10)) ++ (listdigits (n `mod` 10))               

gives:

*Main> listdigits 12345
[1,2,3,4,5]

Add the list together

sumdigits n = sum $ listdigits n                                 

gives:

*Main> sumdigits 12345
15

what we are after is a single number, so recurse

onedigit n = if n < 10 then n else onedigit $ sumdigits n                                                   

gives:

*Main> onedigit 12345
6

now we can repeat for as far though the times table as we want, we expect repeated nines for the nine times table:

do_of n l = map onedigit (take l (times n))                                                                 
*Main> do_of 9 100 
[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]                                                                                                            

the answer to Ellie's original hypothesis, the eights do repeatedly decline:

*Main> do_of 8 100 
[8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1,9,8]

Next we want to display this and other series...

Setup Haskell Plotting

Plotting is not simple, plotting in Haskell is worse. Setup separated into its own post as it took a while.

Once plotting is setup:

main = do 
    plotListsStyle 
        [Title "Multiplication Series Reduced - For Ellie"] 
        [(PlotStyle LinesPoints $ DefaultStyle x ,  (onedigit_tuple x)) | x <- [2..9]] 

we get:

Customise the line labels:

main = do 
   plotListsStyle 
      [Title "Multiplication Series Reduced - for Ellie", 
       YLabel "Reduction", 
       XLabel "Times"] 
      [ (PlotStyle{plotType=LinesPoints, lineSpec=(CustomStyle [LineTitle $ show x])}, (onedigit_tuple x)) | x <- [2..9]]

The whole program

import Graphics.Gnuplot.Simple

listdigits :: Integer-> [Integer]
listdigits n = if n < 10 then [n] 
                         else (listdigits (n `div` 10)) ++ (listdigits (n `mod` 10))

sumdigits :: Integer -> Integer
sumdigits n = sum $ listdigits n 

onedigit :: Integer -> Integer
onedigit n = if n < 10 then n else onedigit (sumdigits n)

onedigit_tuple :: Integer -> [(Integer, Integer)]
onedigit_tuple n = [(x, onedigit( n*x ) ) | x <- [1..19]]

main = do 
   plotListsStyle 
      [Title "Multiplication Series Reduced - for Ellie", 
       YLabel "Reduction", 
       XLabel "Times", 
       Key $ Just ["outside"]] 
      [(PlotStyle{plotType=LinesPoints, 
                  lineSpec=(CustomStyle [LineTitle $ show x])}, 
        (onedigit_tuple x)) | x <- [2..9]]

Setup Haskell Plotting

I explored the space of Haskell Plotting quite extensively. It is dense, plotting is detailed. None of the examples are simple.

chart-gtk

This has extensive tests. I found the examples and tests pretty complex in themselves. This is probably the right place to dig deeper, but for now I have a limited set of goals in mind.


sudo apt-get install libgtk2.0-dev 
sudo apt-get install libpango1.0-dev 
sudo apt-get install libglib2.0-dev 
sudo apt-get install libcairo2-dev

sudo apt-get install  alex
sudo apt-get install  happy

sudo apt-get install gtk2hs-buildtools
cabal install chart-gtk

easyplot

The clue is in the name: easyplot is not. I could get the complex example to work, but I could not understand or modify it. Some nasty asymmetry in types meant I could not adapt this to my simple use case.


sudo apt-get install gnuplot-x11
cabal install easyplot

plot

At last someone with a clue has posted a little thing that works!


cabal install cabal
cabal install gtk2hs-buildtools
sudo apt-get install libcairo-dev
sudo apt-get install liblapack-dev
sudo apt-get install libgsl0-dev
cabal install hmatrix
cabal install hmatrix-gsl-stats
cabal install plot

The simple example works and can be extended:


timp@eric17:~$ ghci 
GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Prelude> import Graphics.Gnuplot.Simple
Prelude Graphics.Gnuplot.Simple> plotList [] [(2,10),(3,15),(4,14),(5,19)]

timp@eric17:~$ ghci 
GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Prelude> import Graphics.Gnuplot.Simple
Prelude Graphics.Gnuplot.Simple> plotList [] [(2,10),(3,15),(4,14),(5,19)]

Sunday, 9 June 2013

Project initiation - a recipe

Like with my cooking blogs this starts out in the future, ends up as what actually happened. I hope this is not too confusing. It is intended as a recipe to make life easy next time I come to use it.

This recipe steals from Hackers gonna Hack.

Choose short name

Ensure this is available on heroku.

Choose stack

I challenge your horse/cart analogy: this is going to be a Django project.

Create Repo

The only decision is public or private. It will be a git repo: here.

Create the README

Do it now!

Choose deployment platform

Heroku.

Choose CI

My Jenkins.

Setup dev machine

Follow Ubuntu Setup recipe.

Use a virtualenv, it is best practice and Heroku needs it.


sudo pip install virtualenv

sudo apt-get install sqlite3
sudo apt-get install ruby-dev
sudo apt-get install libsqlite3-dev


sudo apt-get install postgresql-server-dev-all
sudo apt-get install python-dev

There is a nasty issue with deployment to Heroku: ruby and or ruby gems versions. The problem occurs during heroku db:push with a message about date serialization. This is due to a change in the serialisation of dates. If you have a more recent version of ruby than heroku, and/or you have an inconsistent set of ruby gems. This is made worse by being able to both install Heruku from the Ruby repositories and directly. The recipe below uses RVM and worked.


# setup ruby for heroku pg:push
# this can go wrong if ALL versions are not alligned

\curl -L https://get.rvm.io | bash
source /home/timp/.rvm/scripts/rvm
rvm install ruby-1.9.2-p318
rvm use --default ruby-1.9.2-p290
gem install sqlite3
gem install pg
gem install taps
gem install heroku
gem install launchy
gem install addressable
gem install taps

TODO: pgbackups

Setup project

mkdir ucl
git init ucl
cd ucl
git remote add origin https://github.com/timp21337/ucl.git
git pull origin master
virtualenv venv --distribute
echo venv >> .gitignore
git commit -m "Add virtual env" .gitignore

source  ./venv/bin/activate 
pip install django
pip install dj_database_url
pip install django_jenkins
pip install psycopg2 gunicorn 
pip install django-floppyforms

pip freeze > requirements.txt

heroku login
heroku plugins:install git://github.com/ddollar/heroku-config.git
./manage.py collectstatic 
foreman start
git clone git@heroku.com:ucll.git -o heroku

dropdb --user postgres ucll
createdb --user postgres ucll

./manage.py syncdb;
git push heroku master

heroku db:push --confirm ucll postgres://postgres:*@127.0.0.1:5432/ucll

Results in http://ucll.herokuapp.com/.

Tuesday, 4 June 2013

Canon MG5200 wireless printer driver for Ubuntu (debian) systems

From this thread I found this pretty odd Canon Australia page which works, however do not think that the deb in the download is the universally understood file extension for a debian package, no it is just some guy's way of indicating that this is targeted at debian based systems. What you actually have to do is inflate and ./install.sh, then all works well.