Whole numbers and decimals
Python has two number types for everyday work. An int is a whole number such as 200 shares. A float is a decimal number such as 184.25, a price. type() tells you which one a value is. Counts of things (shares, lots, days) are ints; prices, returns and ratios are floats.
shares = 200
price = 184.25
print(type(shares), type(price)) # <class 'int'> <class 'float'>Three kinds of division
+, - and * behave as you expect. Division comes in three flavours. / always returns a float, even for 10 / 2 (that is 5.0). // is floor division: it divides and rounds down to a whole number. % gives the remainder. ** raises a number to a power.
# Division, floor division, remainder and power
print(7 / 2) # 3.5
print(7 // 2) # 3
print(7 % 2) # 1
print(2 ** 10) # 1024// rounds toward minus infinity, so -7 // 2 is -4, not -3. For positive numbers that looks like dropping the decimals; for negative numbers it does not.How many whole shares can you buy?
Floor division answers "how many times does this fit?". With 1,000 in cash and a price of 184.25, cash // price is the number of whole shares, and cash - shares * price is what is left over. On floats // returns a float (5.0), so wrap it in int() when you need a real count.
# Whole shares for a cash budget, and the cash left over
cash, price = 1000, 184.25
shares = int(cash // price)
left = cash - shares * price
print(shares, left) # 5 78.75Floats are approximations
A float stores a number in binary, and most decimals such as 0.1 have no exact binary form. Python keeps the nearest one, so tiny errors appear. This happens in every language and is not a Python bug. The rule for quants: never compare floats with ==. Use math.isclose, which allows a small tolerance.
# Floats are approximate: compare with isclose, not ==
import math
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
print(math.isclose(0.1 + 0.2, 0.3)) # TrueRounding to a tick
round(x, n) rounds to n decimal places. Exchanges only accept prices on a tick (for example every 0.05), so divide by the tick, round to a whole number of ticks, and multiply back. Also note that round sends an exact half to the nearest even number: round(2.5) is 2 and round(3.5) is 4.
# Snap a price to the nearest 5-cent tick
price, tick = 184.267, 0.05
ticks = round(price / tick)
print(ticks, ticks * tick) # 3685 184.25
print(round(2.5), round(3.5)) # 2 4Money in whole cents
Because floats are approximate, systems that must be exact keep money as an integer number of cents. To convert, multiply by 100 and round. int() only cuts off the decimals, so 19.99 * 100, which is really 1998.9999999999998, would lose a cent.
# Dollars to integer cents: round, do not truncate
amount = 19.99
print(amount * 100) # 1998.9999999999998
print(int(amount * 100)) # 1998 (a cent is lost)
print(round(amount * 100)) # 1999- Counts (shares, lots, days):
int. - Prices, returns and ratios:
float, compared withmath.isclose. - Exact money: integer cents (or the
decimalmodule).
Next up: strings and f-strings, where you turn these numbers into readable text such as AAPL 184.25 x 184.50.
Lab · what's graded
- Count the whole shares a budget buys with
shares_for_cash25 pts - Find the cash left over with
leftover_cash25 pts - Snap a price to the nearest tick with
round_to_tick25 pts - Convert dollars to exact integer cents with
cents25 pts