Money

At first sight it seems obvious to store money amounts as floats as it is normal to have some decimal part to the main unit, be it dollars and cents, pounds and pennies, or euro and cents. However, the difficulty floats have with decimal fractions can lead to trouble with rounding errors.

Use integers

One simple solution is to use integer values, and count money in cents, pennies or whatever the smallest coin is. To extract separate dollar and cent values use divmod() function. The format specifier for the cent value 0 pads it to two characters.


default pcMoney = 9806      # 98 dollars and 6 cents

label exDollarsCents:
    $ dollars, cents = divmod(pcMoney, 100)
    "I have $[dollars:n].[cents:0=2]."

I have $98.06.

With some conditionals the monetary value can be presented in a more natural way:


    $ dollars, cents = divmod(pcMoney, 100)
    if dollars:
        if not cents:
            "I have [dollars] dollars."
        elif cents == 1:
            "I have [dollars] dollars and one cent."
        else:
            "I have [dollars] dollars and [cents] cents."
    else:
        if not cents:
            "I have no money."
        elif cents == 1:
            "I have just one cent."
        else:
            "I have [cents] cents."

I have 98 dollars and 6 cents.

Use Decimal

Python has a dedicated Decimal  type that is designed for accounting purposes. This may be a better option if you plan on doing a lot of arithmetic with money values.

Other systems

There are monetary systems that don't use decimals (such as pre-decimalisation British currency with it's pounds, shillings, pence and farthings), or fantasy systems based on precious metals such as platinum, gold, silver, and copper. These take a bit more work.

British pre-decimal

The smallest coin was the farthing, worth a quarter of a penny. Twelve pennies made a shilling, and twenty shilling make a pound. This system was common across Europe with the abbreviations for the coins originating in the Roman Empire.
See Wikipedia: £sd 

Repeated applying divmod with the correct ratios allows splitting a value in farthings into the right number of pounds, shillings, and pence. The farthings themselves are then converted into a fraction character.


    $ pcMoney = 2797
    python:
        dd, qp = divmod(pcMoney, 4)     # 1 penny = 4 farthings
        ss, dd = divmod(dd, 12)         # 1 shilling = 12 pennies
        ll, ss = divmod(ss, 20)         # 1 pound = 20 shillings
        qf = (                          # Convert farthings to fractions
            "",
            "\N{VULGAR FRACTION ONE QUARTER}",
            "\N{VULGAR FRACTION ONE HALF}",
            "\N{VULGAR FRACTION THREE QUARTERS}"
        )[qp]
    "\u00A3[ll]/[ss]/[dd][qf]"

£2/18/3¼

Fantasy system

Thankfully typical fantasy monetary systems steered away from the complexities of actual historical currencies!


    $ pcMoney = 7654
    python:
        sp, cp = divmod(pcMoney, 10)
        gp, sp = divmod(sp, 10)
        pp, gp = divmod(gp, 10)
    "[pp]pp, [gp]gp, [sp]sp, [cp]cp"

7pp, 6gp, 5sp, 4cp