Monday, 30 December 2013

Multiply Defined moved to wordpress

I have moved multiply defined to wordpress as I found the blogger interface very awkward for writing code snippets.

You can find my new blog at multiplydefined.wordpress.com

Thursday, 23 July 2009

Russian peasant multiplication in python

The Daily WTF recently suggested a programming challenge (or Praxis in their terms) to write a Russian peasant multiplication algorithm. I thought this would be a good opportunity to improve my python programming and inline I have described a few of the python specific techniques I used.

The algorithm itself is very simple:

multiply(a, b)

repeat until a = 0
  1. if a is an odd number add b to the accumulator
  2. divide a by 2 (throwing away the remainder)
  3. multiply b by 2
The accumulator will contain the desired result.




#!/usr/bin/python

from sys import argv

if len(argv) < 3:
print "input values missing"
print "usage: "
print argv[0] + " value1 value2"
exit()

# The int() function converts a string or number to an integer

a = int(argv[1])
b = int(argv[2])
acc = 0 # the accumulator
sep = " x " # separator for output formatting
justWidth = 5 # justification width for output formatting

while (a > 0):
if a & 0x1:
acc = acc + b
print " ",
else:
print "--",

# the str() function converts an object to a string
# rjust(n) right justifies strings to a given width

print str(a).rjust(justWidth) + sep + str(b).rjust(justWidth)

# Only output the x separator the first time round - after that use
# spaces. It is inefficient to continually reset this but IMO makes
# the code clearer than keeping a separate flag.

sep = " "

a = a >> 1
b = b << 1

# The output width is the width of the two numbers plus the
# separator

fullWidth = (justWidth*2)+len(sep)

# A neat python feature is that using the * operator on a string will
# repeat a string a multiple number of times so this line outputs
# 2 spaces followed by (2*justWidth) + separator length dashes

print " " + "-" * fullWidth
print " =" + str(acc).rjust(fullWidth)



This Gives output as follows:


>pmath.py 18 23
-- 18 x 23
9 46
-- 4 92
-- 2 184
1 368
-------------
= 414

The lines starting with -- are considered to be crossed out and only the numbers on the other lines should be added - in this case 46 and 368.

This little experiment has only strengthened my interest in python - it took very little time to come up with this code, even having to learn about int(), str(), rjust() and the * operator for strings. Using the python interpreter command line is also a great bonus to check things like the << and & 0x1 syntax work as expected

Saturday, 20 September 2008

UML Distilled: A Brief Guide to the Standard Object Modeling Language

UML Distilled: A Brief Guide to the Standard Object Modeling Language by Martin Fowler with Kendall Scott does exactly what it says on the subtitle. The easy to read writing style guides you rapidly through the main types of UML diagram before delving into some more depth in later chapters.

At under 200 pages don't expect it to be a full reference but if you have little experience with UML (maybe you've just dealt with class diagrams) this book can take you to the next level.

Buy UML Distilled at Amazon.com

Tuesday, 8 July 2008

What's wrong with this line?

A colleague recently hit this problem when writing some anti-aliasing code.

Imagine you have a block of data in memory, and want to sum blocks of 4 contiguous values. If ptr points to the block of memory do you know what's wrong with this line?
result = *ptr++ + *ptr++ + *ptr++ +*ptr++;

The post-increment operator isn't evaluated until the ; so in effect this code could be doing:
result = *ptr + *ptr + *ptr + *ptr;
ptr += 4;

However it's not even that straightforward. The C++ standard says that variables can only be modified once between sequence points so the result of the first line is undefined.

Writing the code as:
result = *ptr + *(ptr+1) + *(ptr+2) + *(ptr+3);
result += 4;
is much clearer and avoids any unexpected side effects, even though it is a little less efficient.  After all you know what they say about premature optimisation, don't you.

It's really best not to try and be too clever with C/C++ unless it's absolutely necessary and you really know what you're doing.

Monday, 26 May 2008

Safari 3.1 for WIndows

Brief notes on safari:

Font rendering is very different. Personally I find text more readable in Safari, but I can see how it would not the same for everyone, and really depends on what you're used to.

The installer doesn't allow you to choose where you put the program shortcuts.

No way of using Google bookmarks (from Google toolbar).

Safari feels a lot faster in operation navigating around websites.

Safari is much faster for zooming in/out of Google maps.

Some minor niggles:
  • Window resize handles are too small.
  • Middle mouse button doesn't close tabs.
  • Pasting an address is a many click operation (triple left-click or single click on address depending on where the focus was, right click, choose paste). In Firefox it is just right click, paste.

Thursday, 24 April 2008

Using D-Link DWL-G630 AirPlus G with Mac OS X

After having failed to get this wireless LAN PC card under windows (98SE crashes, 2000 worked for a while but has given up now) I thought I'd give it a go under OS X.  There are no OS X drivers on the D-Link site so it seemed like an effort doomed to failure but it is actually remarkably simple.  A discussion on the Apple support site suggests that Ralink drivers may work.  From Ralink's Mac drivers page, download and install the RT28xx driver (v1.0.0.0a dated 3-Dec-2007 for OS X 10.3, 10.4 or 10.5 as I write this).  

The RT61 v1.0.4.0 / RT2500 v1.3.0.0 driver also appears to work OK. There is a problem with both of these drivers: when the Mac goes to sleep with the network card enables it will not wake up again and requires a ctrl-apple-power to bring it back to life.  If you are looking to buy a wireless LAN card, you're probably better off with something else but if it's all you have this is not too much of an inconvenience.


The driver install also installs the snappily named WirelessUtilityCardbusPCI which has a rather strange user interface.  You can connect from the 'Site Survey' tab, but next time you start it will have forgotten your WEP passkey.   It's better therefore to set up a profile, which is most easily done from the 'Site Survey' tab with the 'add profile' button as you don't have to enter all your settings.  It seems that settings are not saved when the utility is exited as part of OS X shutdown so when you've got it working quit the wireless utility to save your settings.  A nice touch is that quitting the wireless utility keeps the wireless connection open.


Wednesday, 26 March 2008

Operafying firefox

After using Opera as my main web browser for about a year I decided to move back to Firefox, my reasons being:
  1. Google toolbar for Opera doesn't support bookmarks.
  2. I wanted to try add-ins such as PicLens.
  3. Some key sites don't work correctly in Opera (internet banking, twiki passwords aren't remembered).
  4. Opera doesn't handle multiple usernames for login forms well.
I missed a few features and the faster startup of Opera. There's not much I can do about the latter, but with a few add-ons much of the functionality that I found useful in Opera could be restored.

Both Fast Dial and Speed Dial offer much of the functionality seen in Opera's speed dial. I chose Fast Dial over Speed Dial mainly because it seems to get more frequent updates and is in a more mature state of development.
You can set Fast Dial to appear on a new tab. It is missing the search box when compared to Opera speed dial, but Firefox supports a search box in the toolbar, or google toolbar.

ImgLikeOpera adds a button to the right of the status bar that will allow you to toggle image loading between on, cached, this site only and off. It also allows you to specify default behaviour for a window or tab, and this can optionally be set to use the current tab/window settings if you have modified them which makes for a confusing settings option but is a useful feature missing from Opera.

There are a few add-ons that can restore the state of your windows and after trying them all I found that Session Manager works the best for me. You can tell it to automatically restore the state that your windows and tabs were in when you closed firefox and it also tries to recover a session after a crash, although I do find the dialog that comes up in this situation somewhat lacking - it calls the pre-crash session the 'current session' and the session state at startup before the crash is called the 'previous session'. To my mind there is no current session as the session has not yet started, and the 'previous session' is the state of my windows before the crash. However this is a minor niggle and it is a very good add-on. It also suppports named sessions and remembers the most recently closed windows and tabs in case you close one by mistake.

I still miss the Ctrl-tab behaviour of firefox (like alt-tab on windows it switches between the tabs in most recently used order rather than tab order), but the other add-ons have covered 90% of Opera benefits for me.

Now I just have to give Safari 3.1 for Windows a go and see how that compares...