Wednesday, 4 November 2015

All about the Teutonic Knights

This post is not about coding, but, I had so much fun with this, I thought I'd share.

The history.  The imdb entry.  The film itself:


Whilst it's in Polish (and sadly lacks subtitles), it still is interesting to watch, and, for the most part, is quite self-explanatory... :-)

If all that is not enough Teutonics for you, there's also this.

(How did I come across this?  By listening to the 'Lesser Bonapartes' history podcast, in particular the episode about rump states.  {Probably the most giggly history podcast series ever})

Tuesday, 27 October 2015

Life is better with hot tea

I make a hot drink.  I go code something.  My drink gets cold.

:(

So, I bought some travel mugs.

The first one had to be returned, it was a Bodum coffee press, which despite the claims made,  is not leak proof and spews hot beverage at times.  Also, the plastic was poorly cured and smelled unhealthy.

I had more luck with the next two models --- they are leak proof and rather good looking.  And they keep the drink warm wherever you take it along with you.

My peppermint tea mug:

You can buy it on Amazon and it's called 'One Click Cup'.
(The somewhat ugly label wipes off with some gentle scrubbing)

My red tea mug:


This you can also buy from Amazon and it's called 'Forge'.

The loop on the purple mug is a nice touch -- you can hook this over a finger and so carry a lot more stuff than you could if you needed to balance a big hot mug, and you can set up a hook on the desk to hang the mug on as well, so it's not in the way and can't fall over. 

Both cups hold 500ml, you can put them safely in your bag, they look cool and they fit into a standard cup holder in the car as well.

Either cup happily deals with a tea bag left in it, and the purple mug is also ok to use with loose Hibiscus or Rosehip tea. 

Happy hacking with spill proof, hot beverages!

Tuesday, 29 September 2015

Tangram for Breakfast

True, you can use software to play Tangram, but it's not as satisfying as the real life hands-on version.

Amazon sells a splendid wooden version for £2.69:

It's the perfect way of (gently) waking your brain up in the morning -- coffee is good, but a Tangram puzzle + coffee is superior.  Also works great if you're stuck on a coding problem -- solve the tangram, and the solution to the other thingy just pops up in your mind a lot of the time.

Try some cats, or a paradox.


Friday, 11 September 2015

A log about writing a logger

So, I finally completed the first cut of my logger, and initially it was a LOT larger than the version in the repository, but after 'test driving', I found that (sadly) all my fancy ideas were just too fancy.

So, it's a pretty small 'opus', and just proves the rule that the shorter a piece of software is, the longer it takes to write.

I found that the ability to define new logging macros, set levels and display options, cherry pick levels to show and defining an output function on the fly really is more than enough for everything that is needed.

Other fails include that my idea to use 'ts -i "%.s"' from moreutils for adhoc profiling didn't really work properly for some reason that I cannot work out why.

If I try to use it with a macro that sets a few printout markers inside a function, all I get is that the expected function printf output stops totally whilst it does it's thing, then I get the total time taken put out on the top line, and everything that I expected to arrive 'peu-a-peu' comes in one go as it's finished doing the time wasting loop test, and it looks suspiciously like it's simply measuring the time it takes for writing to stdout via printf, and that some weird blockage is happening to the stdout output.

Oh well.  Looks like I just have to write something else to have that service :-D




Tuesday, 8 September 2015

The Truth About Git

Just in case you have not seen this yet...


And... for extra added value, you can install magit!

Friday, 28 August 2015

Comments on Comments (1)

(Generosity with questionable benefits) --- from /linux-3.17.1/net/ipv4/ping.c
* Pavel gave all rights to bugs to Vasiliy,  none of the bugs are Pavel's now. 

(History may not repeat, but it will misname things {at least in some versions}) -- /linux-2.4/include/(some versions of)/uaccess.h
* For historical reasons, these macros are grossly misnamed.

(We can't think of much to say here right now, but we're saying something anyway.) --- from Python-2.7.9/Modules/_ctypes/stgdict.c
* XXX blabla more

(What the world really needs is r/codegonewild) -- from git/patch-delta.c
*  /* sanity check */ if (data != top || size != 0) { error("delta replay has gone wild"); }



Sunday, 23 August 2015

A logger for Corinthia

I managed to get the first cut written, and I got use the logmessage scribe.  Took 5 minutes to write the log message, woo!  Profit! :-))

Of course I found a couple of minor bugs in the logmessage scribe, mostly because I had to use GNU diff instead of git diff, but, I could not be happier.


Translation: if you're happy and you know it just say 'meow'!

Tuesday, 18 August 2015

Tree keeping made easy

If you want snazzy tree views for your project of your local drive files and the remote master repository that you can traverse with a browser, just modify this script and set up a cronjob to keep your trees updated.

How does it look?

Download the file itself, load it into your browser and have fun traversing the tree of the Corinthia GitHub repository. (blogger.com and google.drive won't let me paste the file without crippling the links, fair enough, it's 168 directories (and thus links) and usually people who do this kind of thing would probably be up to no good[1]).  If you just want to see it without working links, it's here.




I think it's nice to have a tree overview --- a picture is worth a 1000 words (as they say).

[1] sadly, saving the document also ninja-edits the original.  So, don't waste your time with pasting lots of links into Google Docs :(

Monday, 17 August 2015

Can't sleep?

Listen to Bertrand Russels's Introduction to Mathematical Philosophy.

You probably still won't fall asleep, but it's more productive and it beats counting sheep...


Sunday, 9 August 2015

Adhoc profiling

./YourProgram | ts -i "%.s"

is a quick way of profiling your code.  Does of course not beat the real thing(tm), but for most purposes, this should give you a rough idea where your code spends it's time.

(You may need to install 'moreutils')

Some hacking music... because otherwise, there is just too much margin left in this blog post.


Sunday, 5 July 2015

Introducing Logmessage Scribe

This is my first python project.

It turns patches into logmessage templates, ready for you to produce a great logmessage.

The source (along with a proper introduction about the project) is parked on Bitbucket and the webapp is hosted on Google Appengine

Enjoy!



Tuesday, 23 June 2015

Emotional about Google Emojis

UPDATE:  After updating my browser, options to turn of the ugly ducklings appeared as a selector drop down next to my hangout name.  Still, if you move options to another place, at least leave a forwarding address! (This is why I hate upgraded stuff.  One forever has to hunt around to figure out wither stuff went --- the only thing I enjoy looking for is Easter Eggs...!)

Update to the update:  The ducks are back.  My side of the chat displays duck free, but now, people sending me emoticons still cause a duck invasion on my screen.  Solution:  revert to the old hangout, lose Hangout groups.  Oh well, there's always IRC for group chats I guess.

8():

If you're using Google hangouts or Gmail, you probably have noticed the invasion of hideous blobs that look like demented rubber ducks, where once classic smilies graced your mails and other utterances.

And there is no way of turning this 'feature' off, neither in gmail nor in hangout.

Ve hav ways and mezzods of making you use our stoopid design.

Nope. Not. Even. For. Free.  And not even if you paid me. Gerrroffff my lawn!!!1!!!

(Why so angry?)

I dunno.  It's an invasion of my personal space, and whilst I'm all for new inventions, I don't like being dictated to.  Plus, did I mention those emojis simply are hideous?

And yes, I also resent the waste of time of me having to research and then set up a new email client.

In case you have no idea what I'm talking about, here is a comprehensive collection of kiddie chic eyesores, in their full gory:



Friday, 5 June 2015

The Ultimate Meat in Sauce Method

Most recipes tell you to cut the meat into cubes, fry 'em and then add veg 'n stuff to the pan, and subsequently cook the entire thing for a longish while, often in a slowcooker.

This sort of works, but does the meat no favours and does not really improve the sauce either.

What people like about the slow method is that it breaks down the connective tissues in cheap cuts, but, there is a much better way of achieving the same effect, whilst keeping your other ingredients in prime condition.

Use a pressure cooker, and do the following with any meat-in-sauce recipe of your choice:
  1. Fry your uncut lump of meat on a medium heat setting until brown on all sides.  
  2. Lift out and place into the steam basket.
  3. Add your stock or water to the pan to just below the basket level, put the trivet in and the meat basket back.
  4. Pressure cook the lump in the steam for 25-45 minutes, depending on size and type.
  5. Set cooked lump aside (and cover so it does not dry out), reserve the stock, wipe the pan dry.
  6. Make your sauce as per recipe, without the meat, but use the reserved (and perhaps reduced) stock.
  7. Pressure cook the sauce for 7-10 minutes on the middle or lower pressure setting, use the quick release of steam.
  8. Take a blender stick to the sauce and veg in the pan (optional)
  9. Cut the meat into bite size pieces and add to the sauce.
Freeze in portions once it's all cooled down; or season and re-heat to eat now.

Why is this better?  Because your meat just cooks so much better as a lump (as in, stays juicier and has a much nicer texture and flavour), and the pressure[1] will take care of any connective tissue much better than a slow cooker.  And your veg and spices are not going to be boiled to death but only the amount of time necessary.  Plus, you get to purée the sauce, so it has a nice consistency. (if you use whole spice to cook, use a spice bag to remove them!)

Also, this method of course works for curries (where you sometimes may not want to use the pressure cooker on the actual sauce, but just for the meat) or Au Vin style sauces.

[1] If you're buying a pressure cooker, be very sure that it does deliver 15psi (or, 1 bar) as the top pressure. Otherwise, you need longer cooking times, which in turn affect the taste of the food.  Lots of pressure cookers don't offer that performance that and price is no indicator of quality here.  Beem (a German company) is a very good brand and I have their 8 litre model which I am very happy with. But Tefal, Tower and Kuhn Rikon all max out at 13 PSI, so always check the manual.  If it does not mention the actual numbers, chances are that the pot will not make the grade.  Moreover, if you use your pressure cooker to can food in WECK jars, 15 PSI is mandatory to produce the high temperatures needed to be safe from botulism.

Saturday, 30 May 2015

Everyone is mad about Mad Max

Me, I staying @ home, writing a new (small) project  in python and to chill out, I listen to a proper real life account of real life 'Mad Max' guys --- truly gory stories written in old fashioned, elegantly worded plain English; read beautifully by a man with a most sonorous and peaceful voice.



And, if you liked that, Mr. Roger Melin has read lots more Librivox books.  This book is next on my list. And this too.

Wednesday, 27 May 2015

Put some colour in your C code

I like colours.

Colours make things easier to spot, especially if you have to look at a few metres of test output bumpf --- looking for something blue or pink is much quicker.

So, I made myself a little color.h file that lives in /usr/include/ where it is available anywhere I need some colour in my code.

You will probably notice the colour names --- I took the liberty of renaming 'green' to 'moss', 'bold green' to just 'green' and 'magenta' to 'purple' and so on.  It's less to type, more descriptive, and, also functions as a small cheat map to understand the weird names the fashionistas in your life use to describe colour shades.

You can find the source for color.h here, note that the test code is present in the file in a comment, ready to be copied into a *.c file.

Enjoy!

                                                 

Monday, 25 May 2015

A fake switch

This post is about a trick from the Dalvik VM Internals video, which was mentioned in the Coursera Android course that is currently running. (maybe the next million years will be more exciting?)
                                         
The claim was that this is the one case where goto isn't evil around minute 33:31 and that it performs better than switch.  Well, does it?  And if so, by how much?

This was the example:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define DISPATCH()  \
    { goto *op_table[*((s)++) - 'a']; }

static void interp_old(const char* s)

   static void *op_table[] = { 
   &&op_a, &&op_b, &&op_c, &&op_d, &&op_e };
   DISPATCH();
   op_a: printf("Hell"); DISPATCH();
   op_b: printf("o "); DISPATCH();
   op_c: printf("wo"); DISPATCH();
   op_d: printf("rld!\n"); DISPATCH();
   op_e: return;
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
            
Switch is pretty switched on, so let's see how this compares!

The code that does the comparison can be found here.  Results(on my ancient 32 bit Dell):

With gcc -g:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
Using default value of 100000.  Usage: ./dispatch #
Sample size = 100000 chars * 100000 iterations. 
Dispatch method:                         0.002152 
Dispatch shuffled method:                0.002144
Goto switch method:                      0.002641
Goto switch method 2:                    0.002351
For loop Switch method:                  0.002667
For loop Switch shuffled method:         0.002660 
Recursive switch method:                 0.010798
Recursive shuffled Switch method:        0.006913
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

With gcc -O3:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Using default value of 100000.  Usage: ./dispatch #
Sample size = 100000 chars * 100000 iterations.
Dispatch method:                         0.001083
Dispatch shuffled method:                0.001108
Goto switch method:                      0.001338
Goto switch method 2:                    0.001381
For loop Switch method:                  0.001465
For loop Switch shuffled method:         0.001385
Recursive switch method:                 0.001437
Recursive shuffled Switch method:        0.001385
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

So, there is a small difference, but it's really not that big a deal, unless you really are pressed for time and space.

The ever useful gcc manual has an entry about fun with local labels which will tell you more. Still, building this by hand is tedious, even if emacs is your best friend.  

What if you have a huge array of a struct that maps variable A to variable B and also has an optional function pointer F?  What you need is a 'fake_switch' generator, here is my version.  It should be easily adjustable for your taste. 

Goto it ;-)

Ps.: For extra fun, try this C to Assembler translator.  I really like the hover feature they built, but another thing that would be useful is showing the size of the generated code.
                                                                                                                                                                                    

Thursday, 21 May 2015

Today is... 2 Prairial CCXXIII

The French Republican Calendar episode of 'Revolutions' covers fairly much every aspect of user interface design and every potential pitfall and foible possible.

In fact, I think Mike's podcast is probably the TL;DR of most UI  (and application) design books that are out here (and far more fun too).

Enjoy!

Ps.: I'm not sure why the designer eventually was guillotined, but, I'm also not overly surprised ;-D

Monday, 11 May 2015

Fontic Kharma

I should not have seen this bug never before...

$ ./bin/dfconvert get ../gbg_samples/headers.odt foo3.html
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
DFAttribute *attrs: 0x85c15c0 , Tag tags: 1682 , char *value: DejaVu Sans1 ERROR:  no_op should never be called. 
...

Sunday, 10 May 2015

Programming is fun (when stuff compiles)

Went to a BBQ.  Seemed to be a training session for competitive eating :-)

Came home, got my project's blueprint working.  Got emacs to smoke'n'choke with an M-x indent-region -- no idea what it did there, but it needed 20 minutes to indent gbg_test.h.  Impressive.


This music definitely helped things along :-)

Tuesday, 5 May 2015

How to grab every mp3 from a Feedburner page

My little Apple finally died[1] and the major loss was my collection of the entire History of Rome podcast, by Mike Duncan.  Oh noes!

Sadly, Feedburner doesn't provide a big zip file of all the episodes, which is understandable, since it would be huge.

I could hunt around for a browser extension that does a mass download, but this is quicker, safer and way more fun:

Save the above file to your 'history_of_rome' directory as 'hist.xml'

Preferably overnight(if your 'broadband' comes via the phone line...), in the bash shell do this:

$ grep -e "enclosure url=" hist.xml | sed -e 's/[^"]*"//' -e 's/".*//' | xargs wget

And hopefully, if all goes well, in the morning you'll have this:

FINISHED --2015-05-05 02:06:31--
Total wall clock time: 2h 26m 38s
Downloaded: 191 files, 2.0G in 2h 24m 49s (240 KB/s)

~/history_of_rome>

You say that this podcast is a little bit short for such a long story?  Well, there's lots more out there, but this is my second favourite series:



[1] And, after all this, I found that the Apple actually wasn't broken, but the USB port I plugged in for a recharge was.  ;-D

Monday, 4 May 2015

Shellicious!


Shell Style Guide -- how to code bash scripts in style.

How to scramble eggs inside their shell, for a neat pocket omelette, now with industrial trick:




The expectations of life depend upon diligence; the mechanic that would perfect his work must first sharpen his tools. 
          Confucius

Sunday, 26 April 2015

How to unconfuse someone

Since I am to implement the odf filters for Corinthia, I initially started by copying whatever structure was in the ooxml/word tree and set about deciphering the meaning and plucking out things and plugging them in.

Quite tough going, because it's a pretty, sophisticated piece of code that does a lot of things (much squinting and lots of peppermint tea was involved in the study thereof).  My little opus sort of worked, for some values of sort of.  That is, it compiled and I learned a lot.

But it was a bit of a woolly ball because much of what is in ooxml/word doesn't really apply to odf, so, Peter rescued me and helpfully made a great starting structure for me in this patch:

https://github.com/apache/incubator-corinthia/commit/ccd08368b033293c3607341ad4d25038e349bf9e

So, more peppermint tea, some good hacking music and I'm all set to code this thing ;-)


Saturday, 25 April 2015

Git being a git.

I needed to revert a commit I made.

So....

$ git revert 83720d9ddad4d1021e3cf0b416ebd7a761771cae
Please supply the message using either -m or -F option.

$ git revert 83720d9ddad4d1021e3cf0b416ebd7a761771cae -m "Revert mistaken approach"
error: switch `m' expects a numerical value

$ git revert -m "Revert mistaken approach" 83720d9ddad4d1021e3cf0b416ebd7a761771cae
error: switch `m' expects a numerical value

(writes logmesg file...)

$git revert 83720d9ddad4d1021e3cf0b416ebd7a761771cae -F logmesg
fatal: bad revision 'logmesg'

$ git revert -F logmesg 83720d9ddad4d1021e3cf0b416ebd7a761771cae 
fatal: bad revision 'logmesg'

Grrr.

All that was needed was to simply: 

$ git revert 83720d9ddad4d1021e3cf0b416ebd7a761771cae
$ git commit -a -m "Revert mistaken approach"

Moral: Don't believe everything you read.  Especially not error messages.



Thursday, 23 April 2015

TIL: Nuked Broth + Salt = Instant Geyser

This is not a code post.  But I was very impressed and thought I share this warning.  But sheer luck I avoided what could have been a serious burn on my hands and fingers ;-( )

I made some of my famous broth[1], formed 4 small meatballs and dropped that with a squirt of tomato paste and some parsley into a 1pt pyrex jug and filled it up to 1/2 pt with extra strong broth. Covered it with a silicone mat and nuked it  @600W for 4 minutes and ... added 1/2 teaspoon of salt.

Luckily I poured the salt into my hand and dropped it in from a height --- because the entire thing welled up with a bubbly vengeance and poured forth over the edges of the jug.

Superheated much?  OMG.

Points to make:

  • I was very lucky moving it out of the nuke didn't make it erupt.
  • I was even more lucky not to stick the salt onto a spoon and stir.  To stir this kind of thing, you'd need a long cooking spoon.  But that's not the smart way to do it either.
What I should have done is pull it out at 1 minute intervals and stir it, leave it sit for 20-30 sec before zapping it again.  

Be safe and eat well.

[1] The recipe!

Don't use salt or pepper (and other spices) until you're ready to use the result.  

Hour 0:

Start with a slow cooker or a pressure cooker (because that closes very well).  Set on low heat, you want a very slow simmer, if the pressure valve releases steam, it's too hot.  Ideally, no steam leaves the vessel.

Add 1 kg+ of oxtail or other big bones (break with a hammer if not cut), 2 table spoon of vinegar (to leach the bones' goodness) and cover the bones with boiling water.

Hour 24:

Add those frozen, broken bird bones, gristle, skin and knuckles you carefully have saved in a freezer bag every time you gnawed or otherwise dissected something delicious.   Add more boiling water to just cover.

Hour 40:

Add veggies --- 1/2 a green celery head, 4-6 carrots, 1 -2 quartered onions and if you have it, some chopped celeriac or, chopped parsley root(for the gardeners amongst you).  And a big bayleaf.  Add more boiling water to just cover.

Hour 47 1/2:

Now is the time to optionally add things like parsley stalks (not the leaves) or 1/2 a leaf of lovage (beware.  It's nice but easily dominates, pervasively so).

Hour 48:

Leave it to cool down, now pour the entire thing through a sieve.

Once cooled down:

It should solidify into a jelly.  If not, use bags you put into mugs for easier pouring and tying, before you stick 'em into the freezer (minus the mug).  For small cubes, use the ice cube tray, or silicone muffin cups.  If you have jelly, use a big spoon to carve off pieces, wrap into cling film and freeze. 

The fat is good for frying eggs and other stuff in (skim and heat carefully to evaporate the last bits off moisture), or if you don't like fat, for bribing a deserving doggy with suitably small portioned treats.

You broth stash will go well in soups and the smaller pieces in cling film go well in vegetables and sauces.  

Plus, it makes your kitchen smell great for 2 days. This makes about 1-2 litres of very strong broth, depending on how many bones and water you've used.  Not enough?  Well, make another lot! ;-D


Friday, 17 April 2015

I installed tree and found a useful forest

Today I was idly reading some random unixy stuff, and, came across the 'tree' command.

I had to install it for Ubuntu, but, it definitely was well worth it.

It's s useful if you are connecting with a shell and need to navigate a forest, and also makes a neat html file from any tree you like, which looks good in lynx, or in any web browser for that matter.

The tree gives you the big picture, with tree -d -H . > tree.html


(OMG, I'll be whistling this all day long now.  And so will you ;-D )

Thursday, 16 April 2015

Sometimes, it's not a bug, but a workaround.

I found a few ';;' in the Corinthia source and thought -- aha, typo!  So, I fixed and committed, but alas...

http://www.mail-archive.com/dev@corinthia.incubator.apache.org/msg01164.html

...it's a VC++ bug, it won't do C99 without this little hack.


Monday, 9 March 2015

... and it was such a great idea... :(

tldr: 

Lesson 1: You cannot cheat your way around strlen() by using sizeof(s)/sizeof(s[0]) because you cannot stuff a char *s into a char s[] for free.
Lesson 2: Don't use the clock mechanism in the proggy below, because it's unreliable on hyper-threaded CPUs.
Lesson 3: Don't use floats.

The full story:

I am currently reading the book Modern C.  In it, I came across the advice that you can compute the size of an array by doing  sizeof(s)/sizeof(s[0]).  Hmm, maybe I could use that instead of strlen, because surely this is much quicker!

So... hackety-hack, I made this[1] and got that output:

A: Time spent:           0.045580  count = 35
B: Time spent:           0.180489  count = 34

Then after some fiddling around, I realised that I of course cannot assign a char *s to a char s[] (without paying the full price), despite either form working in strlen().

I mailed my guru about this unsuccess for his entertainment (and that of his colleagues :-) , and the message coming back informed me that clock is considered harmful, and floats are also bad.  Being curious I asked why clock is dodgy (since time.h surely should be sound), and was informed that on a hyper-threaded CPU, it's unreliable, which of course is no good if you're trying to profile anything. Apparently it's better to use this little creation.

So, how to do find out if your cpu is hyper-threaded?  You do cat /proc/cpuinfo and look up the spec. (mine isn't ht but that's no excuse).

[1]
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>

int main (int argc, char *argv[])
{
  clock_t begin, end;
  double time_spent;

  // sadly I can't assign ss to s :(
  // char *ss = "supercalifragilisticexpialidocious";                                
  char s[] = "supercalifragilisticexpialidocious";
  size_t max = 10000000;
  int count;

  begin = clock();

  for (size_t i = 0; i < max; i++)
      count = sizeof(s)/sizeof(s[0]);

  end = clock();
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("A: Time spent:  \t %f  count = %d\n",time_spent, count);

  begin = clock();

  for (size_t i = 0; i < max; i++)
      count = strlen(s);

  end = clock();
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("B: Time spent:  \t %f  count = %d\n",time_spent, count);

  exit(EXIT_SUCCESS);
}

Saturday, 7 March 2015

A little perl alias for git log messages

To get a nice log message for your git diff patch which makes it easy for a reviewer to check your stuff, try this little perl proggy:

alias gitdifflogmesg="perl -ne 'BEGIN {print \"[[[\";} /^\\+\\+\\+ b\\/(\\S+)/ && print \"\\n\\n* \$1\";  /^@\@.*[ *]([^ ]+)\(/ && print \"\\n  (\$1).\"; END { print \"\\n\\n]]]\\n\";}'"

Put this into your .bashrc (as one line), and, grab a patch you made with git diff, and use the alias like so:

cat your.patch | gitdifflogmesg

The output is something like this:

* path/to/modifed-file1.c
   (some_function_a).
   (some_function_b).

* path/to/modifed-file2.c
   (some_function_c).
   (some_function_d).

Now all you need to do is some accounting -- a good 50 char intro line and say what you did with all those functions and your log message is ready for sharing.  Of course not all log messages need this level of scrutiny, but, this goes a long way towards helping your reviewers and also, to help yourself to produce a great patch (or mailing list post).

Note that this does not pick up everything --- new #includes and new functions for example.  Then again, whilst that one liner is kinda cute, this service should really be offered by git itself.  But whilst git doesn't have this feature, this goes a long way towards making log messages easy ;-)

I am not a perl wizard though, I just read the book 'Perl One-Liners: 130 Programs That Get Things Done' -- even if you only read the first 3 chapters, you gain a handy little skill, plus, it's just fun to fiddle with.

Wednesday, 4 March 2015

Corinthia

I am proud to announce that I've been made a full committer and PPMC member of the Apache Incubator project Corinthia.

I'll be coding in C and Javascript, and I'll be looking to help with the editor and whatever else needs attention :-)






Wednesday, 25 February 2015

Your own malloc function, the very lazy way

The problem:  You want your own malloc function, and there are gazillions of them in the code base you're working on.  You could automate editing this lot, but littering the place with lots of custom xmallocs does not appeal, plus, there is are 3rd party libraries and you don't really want to mess with those.

The solution:  3 different ways of solving.  And: How to coax the linker into compliance for the wrap.




My patch, that puts it all together, using CMake.

Sunday, 18 January 2015

Search, and ye shall find (or not)


Tesco.ie search at it's finest:

Search results for 'LIVER'

We have found 1 result for LIVER

Did you mean to search for 'love'?

With much hope, I clicked on the link, but, alas:

Search results for 'love'

We did not find any products to match 'love'


Oh well, I'll just have to stick to liver instead... ;-D

Or... maybe some of Charlie Parker's version of 'Love for Sale':

(Actually, I already bought that, some time ago...)

Friday, 16 January 2015

Today is nmap day

The journey to Ireland was a lot of fun (Wales:  lots of sheep, perfectly lined up pylons and very pretty hills), I love ferry trips, especially if the boat is 200mtrs long and I can get a seat in the front right over the bow.  It was rather stormy, but the stabilisers worked very well, and we left Holyhead just before sunset and arrived to a grand harbour light show in Dublin at night.

{pretty nice artists' impression, I forgot to take my own picture}

With all the housewifely chores done (shopping, unpacking, finding out how the house works etc), it is time to do something productive, and because I of course forgot to copy my code over from campion (which is sitting in a container somewhere for the next few weeks), I won't be doing any coding, but decided that today is nmap day.

Part of the nmap book is online, and it's quite a fun, easy read. (at least, so far... ;-)

Music to go with this study session:





Friday, 9 January 2015

The Raven Dinner Party Recipe

A friend sent me this wonderful 'The Raven' Video.  (gzip and poetry! Oh My!)

It would make a great overlay for Alan Parsons' The Raven song video on the Tales of Mystery and Imagination album.



"The Raven" features actor Leonard Whiting on lead vocals, with Alan Parsons performing vocals through an EMI vocoder. According to the album's liner notes, "The Raven" was the first rock song to feature a digital vocoder."

The entire album is probably one of the finest ever made.  Well worth getting the original Vinyl and a proper old school stereo with serious speakers for.   Everything about it is perfect!

Each song is about one of Poe's stories, here is a sample:                                  
                                        
                      

The Cask of AmontilladoStory mp3Story htmlSong Video
                                                     
The Tell-tale Heart :  Story mp3Story html,  Song Video

The System of Doctor Tarr and Professor Fether :  Story mp3,  Story html,  Song Video 
                                                                                                           
I adore all three of them, ...just don't listen to them before bed time.  They all are a little bit darrrrk...

Candle light, ale (and/or Amontillado, plus Champagne) and fine dining are optional (but highly recommended, for a great themed dinner party experience).

Note that all of the stories are lovely to read aloud and just the right length for the necessary breaks in a 3 course meal.

Bon Appetite!