Spot any errors? let me know, but Unleash your pedant politely please.

Wednesday 24 June 2009

Fax machines : Oh how I hate thee.

Fax machines and washing machines. The both confuse me. Are both designed to be operated by a female brain, perhaps ?

Reminder to self: to use the fax machine at work successfully, feed the paper face down and upside down. Put the paper in before dialling the number, or it won't work. It'll pretend to go through the motions, but it'll fail. The fax machine's printer will not begin to warm up until the faxing is complete, despite needing to print whether the operation was a success or not.

Washing machine : I haven't quite figured it out yet. Anyway: fabric conditioner is for wimps.

Friday 19 June 2009

from x import *

Damn. I instinctively knew this was was bad, but it was in the examples I was given before I got stuck in, and before things got complicated, and stupidly without looking to find out if there was a better way.

I have from x import * and from x import name1, name2 all through my code.

It hasn't actually bitten me yet, but I know that I need to change this. Everywhere.

In some languages, there would be no better way. This kind of import is the way things work, and if there's an ambiguity, it's a compile time issue, where things need to be made explicit/qualified when names are used, or it simply won't work.

There's a similar thing in Ada, where with x; is essentially the same as import x, but everything must be qualified. There's a use x; statement that exposes everything in x. It's not dangerous, like Python's *, but it does make it a bastard to find things. The first rule of Ada was "Never use use".

Note to self: next time I try a new language and something looks like a use, figure out how to not use that 'feature'.

Wednesday 17 June 2009

Code Like a Pythonista: Idiomatic Python

Code Like a Pythonista: Idiomatic Python by David Goodger.

It's a must read. I was surprised at how much I already knew, but it's a great reference, and it has lots of good links at the bottom too.

I wish I'd read this a few months ago, when I started dabbling in Python. I didn't realise how deep I'd get. I though just up to the ankles, but I'm maybe up to my knees by now.

Things I've done right :
  • Used 4 spaces for indents. I always have, in all languages that allowed it. (Though possibly not in examples on this blog, for reasons of laziness)

  • Tried to stick to 80 chars. This is just a habit from my days (and nights) on a VT220.

  • StudlyCaps for classes.

  • Avoided single line compound statements.

  • Practicality beats Purity. Always believed this. Some people try to write optimised code. I try to write readable code, and if it needs to be optimised, refactor later, and litter the code with comments explaining why.


Things I'm naturally graduating toward:
  • I love whitespace. I use tons of it. Always have. It really helps readability. So I may have as many as 10 blank lines between functions. Gradually, this has been reducing. While I'm using Python, the excess whitespace has become annoying. I'm not quite at the 1 line between functions, 2 between classes guideline, but I think I'll naturally get there soon.
    Used None for many default parameters, initialising new objects inside functions. (I didn't really know why, but now I do, and I can fix it where I've got it wrong at the moment)


Things I've done wrong:
  • Used camelCase where I should be using joined_lower. I prefer camelCase, but if joined_lower is more Pythonic, I'm willing to yield this. Not sure if I'll change all the code that I already have though.

  • Not used spaces after , and : in lists and dicts

  • Not used docstrings much (My excuse is that I'm in a mixed Java/Jython environment, and I don't know how to make the docstrings useful).

  • I have some unnecessary "== True" or "== None" gubbins. The linked doc has a table explaining how the Truth Values work.

Lovely MISO font from omkrets

Don't know much 'bout typography, I quite like Papyrus, for example, which is probably wrong, but I do despise Comic Sans, so my eyes must work a bit…

There's a lovely looking free font available from omkrets called Miso:

Picture of MISO font

There are different weights, but they're equally spaced, so you can have normal and bold fit into the same space. The technical terms from the PDF descibing the font are 'Equal stroke height, varying baseline' and 'equal glyph width'. Maybe lots of fonts do this, but it looked like genius to me.

I think I'd like a monospaced version for coding with, but there are probably very good reasons why this won't work. Are there any good sans serif monospaced types ? Would the 'i's would look all wrong ?

Tuesday 16 June 2009

New MacBook Pros and the missing ExpressCard slot

I'm in full agreement with Matt Davis, that replacing the ExpressCard slot on the MacBook Pros with an SD card slot makes little sense.

Some people love that they now have an SD card slot. I get that. I still think it sucks.

The pros need connectivity, and while the unibody enclosures and battery life are superb, the compromise has been connectivity.

Audio people use firewire drives and firewire audio devices. At the same time. They use express card to connect to pro equipment

Video people use firewire drives and firewire audio devices at the same time too. They use the expresscard slot for reading and writing SxS at high speed, and also for specialist pro equipment.

If people really wanted an SD card reader, they could've just bought one for the expresscard slot.

The real test, though, is if people switch to Windows, or go for the 17", which still has expresscard. Is it really the hardware that matters, or is it software. If it's hardware, they'll switch. I'm not switching any time soon.

Tuesday 9 June 2009

Python: Finding out if a class is a subclass of a class

I needed to find out whether a class was a subclass of another. Googling, I found a message by Armin Rigo on the Python-Dev mailing list with this line :
    for basecls in type(obj).__mro__:

A quick look squizz at __mro__, enough to see that it represents 'method resolution order'. (I'll look in more details at some point, but that phrase was enough for now). A bit of a distillation at the Python command line, and I end up with this simple test/condition:
    <ParentClass> in <ChildClass>.__mro__

Monday 1 June 2009

Determine current stack depth

If anyone knows of a better way to do this, do let me know...

The test harness I'm writing produces a lot of logging information. It's necessary to record what test are doing, where they fail etc, so that we can investigate and not just produce yet more useless metrics. One of the things I found myself doing was adding indentation so that the test cases, sub tests and test steps etc were shown with increasing indentation. As with source code, it makes the scope of the test results easier to follow.

The more I was adding this by hand, the more I though that maybe there was a better way to do things. I'm probably going to so something a little more intelligent, but for now I've gone with indenting my logs according to the call depth of the function that writes the log string.

At a fairly high level, there is a routine to print to the console and to a log file. References to this cascade through the code, so that this one function is the one that actually gets called when logging :

def printAndLog(self, logText):
print logText
self.log(logText)


All I need to do is determine the stack depth:
def callDepth():
depth = 0
while True:
try:
sys._getframe(depth)
depth +=1
except:
return depth - 1

and use it to add indentation...
def printAndLog(self, logText):
logText = ' ' * self.callDepth() + logText
print logText
self.log(logText)

Not sure that it's entirely legit to be calling _getframe, but it's working at the moment, and I'm not doing anything with the returned frames anyway.