Old Money

And more adventures with Python programming. One of the trickiest problems in British history is dealing with pre-decimal currency. Until 1971 British currency was a bit strange to say the least. There were 12 pence in a shilling and 20 shillings in a pound (so a pound had 240 pence). This is obviously not something that most off-the-shelf software can deal with, but doing calculations on old money is something that historians need to do quite a lot. During my PhD, when I was using Access databases, I had to decimalize amounts of money before I could do anything with them. That was awkward because some values in the pence column (I seem to remember that 4 and 8 were particularly annoying) gave a recurring fraction. To make things easier I arbitrarily rounded the pence values to the nearest multiple of 3, which meant that my figures were less exact than they could have been, but in practice I could live with it.

These days I can do better. Below are some technical details of how I approached the problem in Python (I like traaaainspotting…).

First I created a class to represent amounts of old money. Having first learnt about OOP in C++ I find Python objects a bit strange (members can’t be private! you don’t have to declare member variables in the class definition!! you can create and assign any member variables from anywhere!!!) but they work very nicely. This is the start of the class definition:

class OldMoney:

    def __init__(self, ps=0, ss=0, ds=0, ex=True):
        self.pounds = ps
        self.shillings = ss
        self.pence = ds
        self.exact = ex

The first function is what isn’t called a constructor in Python. It initializes new instances of the object with the variables that I want it to have. There are integers for pounds, shillings, and pence, and a boolean field to say whether the values are exact. This is to help deal with the fact that some documents have illegible or missing bits which might obscure some of the information. Where this happens with a money value the XML tags will be present but empty to indicate that the value isn’t known. When the XML is converted to OldMoney objects in the Python script the empty tags need to be converted to 0 because trying to do calculations on null values won’t work. Therefore I need some way to tell whether a 0 represents a 0 explicitly stated in the document (in which case we can arrive at an exact total) or whether it represents an unknown figure (in which case calculations involving this figure can only give us a minimum, not an exact total).

But how do we do calculations with these objects? Fortunately Python allows classes to redefine operators, which makes it easy to add, subtract, compare etc. custom objects. The most basic step for any operations on an amount of old money is to convert it into a single number of pence. This is something that will be happening a lot, so I wrote a function to do it:

def toPence(self):
    pencetotal = self.pence + (self.shillings * 12) + (self.pounds * 240)
    return pencetotal

One of the many advantages of converting to pence before doing anything is that it doesn’t matter if there’s an unexpected value in one of the columns. For example, although 20 shillings made a pound, it isn’t uncommon to find shilling values higher than 20. You might find 50s written instead of £2.10s. If that’s what you find in the document you can preserve it in the XML (meaning it’s closer to the original information, and it’s less work when you’re tagging) but still do calculations on it with no problems. The above function is called by all the functions which redefine operators for the OldMoney class. For example, here is the function that redefines the + operator:

def __add__(self, r):

    #convert objects into single number of pence
    ltotal = self.toPence()
    rtotal = r.toPence()

    #create temporary object to hold result of addition
    tempmoney = OldMoney()

    #add total pence together
    tempmoney.total = ltotal + rtotal

    #find number of pounds
    tempmoney.pounds = int(tempmoney.total/240)

    #find number of pence left over after pounds
    leftforshillings = tempmoney.total % 240

    #divide remainder into shillings
    tempmoney.shillings = int(leftforshillings/12)

    #divide remainder into pence
    tempmoney.pence = leftforshillings % 12

    del tempmoney.total

    return tempmoney

I also redefined -, ==, >, <, >=, and <=. You can also redefine += and -= but it looks like they just work as long as you’ve defined + and -. I also needed to write a new sum function as the built in one doesn’t work with custom objects. This takes a sequence of OldMoney objects and returns the total as an OldMoney object:

def sumOldMoney(monies):
    total = OldMoney()
    for x in monies:
        total += x
    return total

And this function takes an XML object containing pounds, shillings, and pence tags, and returns an OldMoney object. It uses a version of the xmltext() function that I mentioned the other day, but I’ve changed it since then so that it returns the text content as a string, or None if there is no text data.

def xmltoOldMoney(moneyelement):
    money = OldMoney()
    ltag = moneyelement.getElementsByTagName('pounds')
    stag = moneyelement.getElementsByTagName('shillings')
    dtag = moneyelement.getElementsByTagName('pence')
    if xmltext(ltag[0]):
        money.pounds = int(xmltext(ltag[0]))
    else:
        money.exact = False
    if xmltext(stag[0]):
        money.shillings = int(xmltext(stag[0]))
    else:
        money.exact = False
    if xmltext(dtag[0]):
        money.pence = int(xmltext(dtag[0]))
    else:
        money.exact = False

    return money

If any tag is empty the exact variable is set to False to indicate that there is missing data and we will only get a minimum from calculations on this object.

Putting all this together, it was very easy to pull a lot of records out of an XML file and add up the money from each warrant. This showed that the sample of 50 warrants I’ve been working with, issued over a few days in August 1642, authorized the payment of nearly £14,000. War is expensive…

Permanent link to this post

Digital History, Early Modern, English Civil War, History — posted by Gavin Robinson, 5:18 pm, 22 December 2007

10 Comments »

RSS feed for comments on this post.

TrackBack URI

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

If your comment does not appear, it has been held for moderation. Please do not submit it again.