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