Turn a rule into a callable calculation
Consider a fictional long holding. Its marked value is the number of units held multiplied by the USD mark per unit. This example deliberately accepts only non-negative whole-unit quantities and whole-dollar marks; it excludes fees, currency conversion and instrument multipliers.
def position_value(quantity: int, mark_usd: int) -> int:
"""Value a long holding in whole USD under the stated input contract."""
if type(quantity) is not int or type(mark_usd) is not int:
raise TypeError("use whole units and whole USD")
if quantity < 0 or mark_usd < 0:
raise ValueError("quantity and mark must be non-negative")
return quantity * mark_usd
print(position_value(2, 100))
# 200
print(position_value(3, 100))
# 300The function definition gives the rule a name. Each call supplies inputs, runs the checks and returns an output. Changing the quantity from 2 to 3 changes the value from USD 200 to USD 300; the definition stays the same. A real position can require fractional quantities, more precise prices or signed holdings, so this teaching contract must change before using the function for those cases.
The example connects four building blocks:
| Building block | Its job here | What it grows into |
|---|---|---|
| Data and data types | Integers represent quantity and the whole-dollar mark | Instrument records, dated observations and position tables |
| Expressions | Multiplication computes the marked value | Pricing formulas and transformations |
| Control flow | if chooses whether to raise an error or continue | Branches for different cases; loops over many positions |
| Functions | position_value packages the rule behind explicit inputs and an output | Small calculations composed into a valuation pipeline |
print is a separate step.Running successfully is only the first check
int annotations describe intended types. They do not enforce them at runtime; the explicit if statements perform the checks shown here. Even those checks cannot establish that a mark is in USD, belongs to the right instrument or is valid at the valuation time. Those are parts of the domain contract: what each input means, which cases are permitted and what the output represents.assert position_value(2, 100) == 200
assert position_value(0, 100) == 0
try:
position_value(-1, 100)
except ValueError as error:
print(error)
# quantity and mark must be non-negativeunittest supplies assertions for values and expected exceptions, including a failure when an expected exception never occurs.Tests supply evidence for the cases they check. They cannot rescue an incorrect financial specification: a perfectly implemented multiplication still misvalues a contract if the required multiplier was omitted. Programming makes the rule inspectable and repeatable; domain review and tests make mistakes easier to find.
Both blocks were executed with Python 3.14.4 using only built-ins. The integers make these whole-dollar calculations exact; this is not a prescription for representing every financial amount as an integer number of dollars.
Start building the pieces
- Python Syntax and Control Flow traces expressions, decisions and loops using a trading signal.
- Functions develops parameters, returned values, local names and input–output contracts.
Sources
- Python 3.14 documentation: An Informal Introduction to Python, arithmetic, numeric types and assignment.
- Python 3.14 documentation: More Control Flow Tools,
if,for, defining functions and returned values. - Python 3.14 documentation: typing, the runtime treatment of annotations.
- Python 3.14 documentation: unittest — Basic example, checks for expected results and exceptions.