Data Types
Concepts covered: Data Types, Type Conversion
The type decides what an operator does
Every value carries a type, and an operator inspects the types of its operands before deciding what to do. * between 2 ints multiplies. * between a str and an int repeats the text that many times. * between a str and a float has no meaning and raises TypeError. The symbol is identical in all 3 cases; the types pick the behaviour. The 4 types met on every line of a data job are int for whole numbers of any size, float for numbers with a fractional part, str for text, and bool for True and False.
raw_quantity = "3"
print(raw_quantity * 3)
print(raw_quantity + raw_quantity)Output:
333 33
Both lines run and both answers are wrong. With an int, * repeats the text, so 333. Between 2 strings, + joins them, which is how the loader turned 3 and 3 into 33. Multiplying the text by the float 49.99 instead raises TypeError: can't multiply sequence by non-int of type 'float', because repetition needs a whole count. That error is the kinder outcome: it stops the job on the failing line, while a plausible wrong number reaches the warehouse unnoticed.
Converting between types
Each type's name is also a function that builds a value of that type from another one. int("3") parses the text and returns the integer 3; int("49.99") raises ValueError: invalid literal for int() with base 10: '49.99' because the text holds a decimal point, while float("49.99") accepts it. int(" 3 ") with surrounding whitespace works, and int("3 units") does not. Values read from a CSV file or an HTTP query string stay strings until the code converts them, and so do environment variables, which is why a loader's first job is usually a column of conversions.
print(int("3") + 1)
print(float("49.99") * 2)
print(str(8814) + "-A")
print(int(49.99))
print(round(48.5), round(49.5))
print(bool(0), bool(""), bool("0"))
print(True + True)Output:
4 99.98 8814-A 49 48 50 False False True 2
Conversion toward a narrower type loses information. int(49.99) is 49: the fractional part is discarded rather than rounded, and int(-49.99) is -49, truncating toward 0. round() is a separate operation: round(48.5) is 48 and round(49.5) is 50, because Python rounds a half to the even neighbour to avoid bias across many sums. bool() is False for zero numbers, the empty string, None and empty containers, and True for nonzero numbers and non-empty strings, including the text "0", so a flag that arrives as "0" goes through int first. True + True is 2 because bool is a subclass of int, which lets a sum over comparisons count matching rows.
int for the quantity, because a count of items is whole and later code will use it to loop or to index. float for the price, because the fractional cents matter. float on the quantity would still give the same line total but prints the count as 4.0, and a label built from it would read as 4.0 units; str on either leaves text in place, and text multiplied by text is the TypeError from the top of the section.
Why 0.1 plus 0.2 is not 0.3
A float is a binary fraction with a fixed number of bits, and most decimal fractions have no exact binary form, the same way 1/3 has no exact decimal form. 0.1 + 0.2 evaluates to 0.30000000000000004. Each error is tiny, roughly 1 part in 10 quadrillion, but it accumulates across a sum of thousands of rows and shows up as a total that differs from the ledger in the last cents. Money is therefore stored as an integer count of cents, which is why the running example carries unit_price_cents = 4999 rather than 49.99, and converted to dollars only at the moment a human reads it.
- 53 bits
One more value sits beside the 4 types: None, the single object Python uses for a missing value. A database driver returns SQL NULL as None and a JSON null parses to it, while an empty CSV field arrives as the empty string "", on which int("") raises ValueError. The check is amount is None, with is, because only one None exists. Adding a None onto a running int total raises TypeError: unsupported operand type(s) for +: 'int' and 'NoneType', which is how one empty row stops a nightly sum.
About this lesson
This section is part of the Python Foundations: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.