Python Foundations for Data Work
Master core Python syntax and tooling for data tasks, from environments and notebooks to clean, reliable scripts.
Content
Numbers and Arithmetic
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Numbers and Arithmetic — Python Foundations for Data Work
"If data is the story, numbers are the punctuation. Learn to read them right, or your conclusions will run on forever."
You're already familiar with variables, types, and casting, and you know how to make strings shine with f-strings. Now we're getting into the part of Python that actually does the math your data project depends on: numbers and arithmetic. Think of this as upgrading from a calculator app to a precision instrument — with a few traps on the way.
What this section covers (quick map)
- Core numeric types in Python: int, float, complex (plus Decimal and Fraction for special cases)
- Arithmetic operators and precedence
- Common gotchas (floating-point precision, negative floor division)
- Practical tips for data work (formatting, comparisons, when to use Decimal or numpy)
Numeric types — when to use what
| Type | What it is | Use this when... |
|---|---|---|
| int | Integer, arbitrary precision | Counting, indices, exact whole numbers |
| float | Double-precision floating point | Measurements, averages, general science/math (fast, but imprecise) |
| complex | Complex numbers like 3+4j | Signal processing, some linear algebra |
| Decimal (from decimal) | Decimal fixed-point | Money, when base-10 exactness matters |
| Fraction (from fractions) | Exact rational numbers | Exact ratios, when you want math with no rounding |
Example quick look:
x = 42 # int
y = 3.14 # float
z = 2 + 3j # complex
from decimal import Decimal
money = Decimal('19.95')
from fractions import Fraction
half = Fraction(1, 2)
Note: bool is a subtype of int (True == 1, False == 0). Yes, True + True == 2. Welcome to Python.
Arithmetic operators & examples
- Addition: +
- Subtraction: -
- Multiplication: *
- Division (float): /
- Floor division: //
- Modulo (remainder): %
- Exponentiation: ** (and pow())
- Augmented assignment: +=, -=, *=, etc.
a = 7
b = 3
print(a / b) # 2.3333333333333335 (float)
print(a // b) # 2 (floor division)
print(a % b) # 1 (remainder)
print(a ** b) # 343 (7**3)
# augmented
a += 2 # a becomes 9
Micro gotcha: floor division with negatives uses floor, not truncation:
-3 // 2 # -> -2 (because floor(-1.5) == -2)
If that feels wrong, you're right to feel suspicious — it's a subtlety you'll hit in data transformations and time arithmetic.
Operator precedence (short cheat)
- Parentheses ()
- Exponentiation **
- Unary + and -
- *, /, //, %
- +, -
Example:
2 + 3 * 4 # 14, not 20
(2 + 3) * 4 # 20
Floating point precision — the inevitable weirdness
You're writing data code and test 0.1 + 0.2 == 0.3 and it fails. Why does Python hate you? It doesn't — binary floats can't exactly represent some base-10 fractions.
0.1 + 0.2 == 0.3 # False
0.1 + 0.2 # 0.30000000000000004
Solutions:
- For display: format or round
- f-strings:
f"{value:.2f}"— you used f-strings earlier; same trick applies here.
- f-strings:
- For numeric comparisons: use math.isclose()
- For exact base-10 money: use Decimal
- For rational math: use Fraction
Example with Decimal:
from decimal import Decimal
Decimal('0.1') + Decimal('0.2') == Decimal('0.3') # True
But Decimal is slower and slightly more tedious, so reserve it for things like financial calculations where rounding rules must be exact.
Comparing numbers safely
Don't compare floats with ==. Use math.isclose or specify tolerances yourself:
import math
math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9) # True
For data pipelines, pick an epsilon that matches domain tolerances (e.g., 1e-6 for many stats tasks).
Handy patterns for data work
- Formatting numbers for reports or logs (you already love f-strings):
avg = 3.14159265
print(f"Average: {avg:.3f}") # Average: 3.142
- Use // and % to split values (e.g., minutes and seconds):
seconds = 367
minutes = seconds // 60 # 6
remaining_secs = seconds % 60 # 7
- Use pow with modulus for fast modular exponentiation (common in algorithms):
pow(3, 100, 13) # computes 3**100 % 13 efficiently
- When scaling vectors of numbers, prefer numpy arrays (vectorized, fast) rather than list comprehensions for large datasets.
Quick tips & pitfalls checklist
- Use int for counts and indices. No one wants fractional rows.
- Use float for measurements and general math — but be mindful of precision.
- Use Decimal or Fraction when exactness matters (money, precise rational math).
- Use math.isclose for float equality checks.
- Remember -3 // 2 == -2 (floor division). If you want truncation toward zero, use int(a / b).
- Complex numbers exist. You probably won't use them every day, but they're ready when needed.
"This is the moment where the concept finally clicks: numbers are not just values — they are promises about precision and behavior. Choose the right one."
Summary — what to remember
- Types: int, float, complex, Decimal, Fraction — pick the right tool.
- Operators: +, -, *, /, //, %, ** — precedence matters.
- Floating-point surprises are normal: format for display, isclose for comparison, Decimal for exact base-10.
- For data science: when working with arrays and performance, migrate numeric work to numpy early.
Final memorable image: imagine floats as slightly wobbly rulers and Decimal as a laser-measurement device — both measure, but one gives you quiet confidence when it must be exact.
Key takeaways:
- Use f-strings to format numeric output cleanly (you already know these!).
- Avoid equality checks on floats; prefer isclose.
- Use Decimal for money and Fraction for exact rational math.
- Be mindful of floor division with negatives and operator precedence.
If you want, I can provide a short set of practice exercises (with solutions) that reinforce these points — including a couple of little puzzles that trap the common mistakes. Want those?
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!