013. Type Conversion
Explicit conversion is safer than implicit coercion
013. Type Conversion
Aryan’s RAM monitor reads its config from a file like this:
warn_threshold_mb = 512
kill_enabled = true
check_interval_sec = 0.5Every value arrives as a string. Python’s file I/O doesn’t know that 512 is a number — it just sees the characters “5”, “1”, “2”.
Aryan must explicitly convert:
"512"→int(...)for the threshold"0.5"→float(...)for the interval"true"→bool— but NOTbool("false")!
The classic trap: bool("false") returns True because any non-empty string is truthy. He must compare the string to “true” instead.
The broken code does the int and float conversions but gets the boolean wrong — it uses bool() directly, so both “true” and “false” return True.
💡 Fun fact: Python’s explicit conversion philosophy (“Explicit is better than implicit”) is encoded in PEP 20 — The Zen of Python. Unlike JavaScript, which silently coerces "5" + 3 to "53", Python raises a TypeError. This strictness was a deliberate choice to make bugs visible rather than hidden.
⚠️ Watch out: bool("false") returns True — because any non-empty string is truthy in Python. bool() tests emptiness, not string content. This trips up nearly every beginner reading config files; always compare the string directly: active_str.lower() == "true".
🤔 Think about it: Python’s int("3.14") raises a ValueError, but int(float("3.14")) works. Why does int() refuse to parse a decimal string directly, and what does that tell you about Python’s approach to type conversion safety?
Learning objectives
- Convert strings to int and float with int() and float()
- Understand why bool() fails for “true”/“false” strings
- Convert string booleans correctly using string comparison
Key concepts
- type conversion
- int()
- float()
- bool()
Try it
Concept detail
Type conversion (casting) explicitly changes a value from one type to another. Python’s built-in converters: int(), float(), str(), bool(), list(), tuple(), set().
Common patterns: int(“42”) → 42 float(“3.14”) → 3.14 str(100) → “100” int(“3.14”) → ValueError — use float() first, then int()
The classic trap — bool() on strings: bool(“true”) → True (non-empty string) bool(“false”) → True (non-empty string!) bool(“0”) → True (non-empty string!) bool(“”) → False (empty string)
bool() checks if the argument is “truthy” (non-empty, non-zero, non-None). It does NOT parse string content. “false” is a 5-character string, so it’s truthy.
The correct way to convert “true”/“false” strings: active_str.strip().lower() == “true”
This compares the normalised string content and returns a real Python bool. .strip() handles accidental whitespace, .lower() handles mixed case.
Explicit is better than implicit: Python won’t silently coerce types the way JavaScript does. That’s a feature — it forces you to think at boundaries.
Solution
def parse_record(age_str, score_str, active_str):
age = int(age_str)
score = float(score_str)
active = active_str.strip().lower() == "true"
return {"age": age, "score": score, "active": active}Tests
def test_age_is_int():
result = parse_record("25", "98.5", "true")
assert type(result["age"]) == int
assert result["age"] == 25
def test_score_is_float():
result = parse_record("25", "98.5", "true")
assert type(result["score"]) == float
assert result["score"] == 98.5
def test_active_true():
result = parse_record("25", "98.5", "true")
assert result["active"] == True
def test_active_false():
result = parse_record("30", "70.0", "false")
assert result["active"] == False
def test_active_case_insensitive():
result = parse_record("30", "70.0", "TRUE")
assert result["active"] == True