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.

Sunday 2 June 2013

Dual boot OSX and Ubuntu

This has been one of the least pleasant Linux experiences, but then aren't they all!

As Mike Orr put it:

Linux Air
Disgruntled employees of all the other OS airlines decide to start their own airline. They build the planes, ticket counters, and pave the runways themselves. They charge a small fee to cover the cost of printing the ticket, but you can also download and print the ticket yourself. When you board the plane, you are given a seat, four bolts, a wrench and a copy of the Seat-HOWTO.html. Once settled, the fully adjustable seat is very comfortable, the plane leaves and arrives on time without a single problem, the in-flight meal is wonderful. You try to tell customers of the other airlines about the great trip, but all they can say is, "You had to do what with the seat?"

Many sites cheerfully claim that there is no problem dual booting a mac to run Ubuntu. eg life hacker. I beg to differ!

My mac is a MacBookPro8.2, 2011 build. As shown by:

dmidecode |grep -i macbookpro

A twist is that it has an SSD where its optical drive should be, so I have to install from an external USB CD drive (I tried from a USB memory stick but ran into other problems).

It seems as though there were problems with the previous (12.04) version of the Ubuntu installer such that a problem with the usb cd provoked an issue with the video driver, or some such. I installed rEFIt and fiddled around for an age. I produced black backgrounds, purple backgrounds and even turquoise backgrounds, but no X.

I managed to install a server version of Ubuntu, but could not get ubuntu-desktop to load. By removing quiet and splash from the grub config I could see the X server crash.

Fatal server error:
no screens found

From wikipedia:MacBookPro I found I have dual graphics cards, an Intel card and an AMD Radeon HD 6490M.

From recovery mode boot I was able to see the real culprit:

fb: conflicting fb hw usage inteldrmfb vs EFI VGA - removing generic driver

I reinstalled from the ubuntu mini iso the latest (13.01) Ubuntu. Got the same conflict error. I installed the latest rEFId using a .deb. Still the same error, but now understand it is a conflict between the driver installed by rEFId and the Radeon driver.

From this thread I was able to find an incantation which worked!

  outb 0x728 1 
  outb 0x710 2 
  outb 0x740 2 
  #Power down ATI 
  outb 0x750 0
  linux /boot/vmlinuz-3.5.4-030504-generic root=/dev/sda4 video=efifb i915.modeset=1 i915.lvds_channel_mode=2 i915.lvds_use_ssc=0

This can be put into /etc/grub.d/00_header and then

grub-mkconfig -o /boot/grub/grub.cfg