Data Types - Different Kinds of Information

Think of data types as different kinds of containers: a water bottle (holds liquid), a lunch box (holds food), and a jewelry box (holds small items). Each holds different things, just like data types hold different kinds of information.
In Python, every value has a specific **data type**. The data type tells Python how to store and manipulate that value. Think of it as a container's label – you wouldn't pour water into a cardboard box, and Python won't treat text like a number unless you explicitly convert it.

**The four most common basic data types are:**

1. **String (`str`)** – Any sequence of characters enclosed in single `'` or double `"` quotes. Used for text, names, messages, etc. Examples: `"Hello"`, `'Python'`, `"123"` (even numbers in quotes become text).

2. **Integer (`int`)** – Whole numbers without a decimal point. Can be positive, negative, or zero. Examples: `42`, `-7`, `0`, `1000`.

3. **Float (`float`)** – Numbers that contain a decimal point. Used for measurements, temperatures, prices, etc. Examples: `3.14`, `-0.5`, `98.6`, `2.0`.

4. **Boolean (`bool`)** – Represents truth values, only two possibilities: `True` or `False`. Note the capital T and F – Python is case‑sensitive. Used in conditions and logic.

**Checking a variable's type:**
Use the built‑in `type()` function. It returns the type of the value stored in the variable. Example: `type(age)` returns `<class 'int'>`.

**Dynamic typing (what makes Python flexible):**
Unlike some languages (Java, C++), Python does not require you to declare a variable's type. The same variable can hold an integer, then later a string, then a float. Python figures out the type automatically based on what you assign. This is called *dynamic typing*.

**Converting between types (type casting):**
Sometimes you need to change a value's type. Python provides built‑in functions:
- `int()` – converts to integer (e.g., `int("42")` → `42`)
- `float()` – converts to float (e.g., `float("3.14")` → `3.14`)
- `str()` – converts to string (e.g., `str(100)` → `"100"`)
- `bool()` – converts to boolean (most values are `True`, except empty ones like `0`, `""`, `[]`)

**Why data types matter:**
- Operations behave differently based on type: `"10" + "20"` → `"1020"` (string concatenation), but `10 + 20` → `30` (numeric addition).
- Type errors occur when you mix incompatible types (e.g., `"5" + 3` raises `TypeError`).
- Knowing types helps you debug and write predictable code.

**Common beginner pitfalls:**
- Forgetting quotes around text – Python thinks it's a variable name.
- Using `=` instead of `==` in conditions.
- Assuming `input()` returns a number – it always returns a string. Convert with `int()` or `float()`.
- Comparing different types directly – `5 == "5"` is `False` because types differ.

**Practice exercises:**
1. Create variables of each type (string, int, float, bool) and print them along with their types using `type()`.
2. Try to add a string and an integer – see the error, then fix it by converting.
3. Convert a float to an integer (e.g., `int(3.99)`) – notice it truncates, not rounds.
4. Use `bool()` on different values: `bool(0)`, `bool(1)`, `bool("")`, `bool("hi")` – observe the results.

**Real‑world use:**
- Strings store user input, file contents, API responses.
- Integers store counts, indices, IDs.
- Floats store measurements, prices, coordinates.
- Booleans control program flow (`if`, `while`), flags, and settings.
# ========== EXAMPLE 1: Creating Variables of Different Types ==========
print("=== Example 1: Basic Data Types ===")
name = "Sarah"        # String (text)
age = 30              # Integer (whole number)
temperature = 98.6    # Float (decimal number)
is_raining = False    # Boolean (True/False)

print(f"Name: {name}, Type: {type(name).__name__}")
print(f"Age: {age}, Type: {type(age).__name__}")
print(f"Temperature: {temperature}, Type: {type(temperature).__name__}")
print(f"Is Raining: {is_raining}, Type: {type(is_raining).__name__}")
print()

# ========== EXAMPLE 2: Dynamic Typing (Changing Types) ==========
print("=== Example 2: Dynamic Typing ===")
value = 42
print(f"value = {value}, type: {type(value).__name__}")

value = "Now I'm text"
print(f"value = {value}, type: {type(value).__name__}")

value = 3.14
print(f"value = {value}, type: {type(value).__name__}")

value = True
print(f"value = {value}, type: {type(value).__name__}")
print()

# ========== EXAMPLE 3: Type Conversion (Casting) ==========
print("=== Example 3: Type Conversion ===")
num_str = "123"
num_int = int(num_str)   # Convert string to integer
num_float = float(num_str)  # Convert string to float

print(f"Original string: '{num_str}', type: {type(num_str).__name__}")
print(f"After int(): {num_int}, type: {type(num_int).__name__}")
print(f"After float(): {num_float}, type: {type(num_float).__name__}")

# Convert number back to string
age = 25
age_str = str(age)
print(f"\nNumber {age} as string: '{age_str}', type: {type(age_str).__name__}")

# Boolean conversion examples
print("\nBoolean conversion:")
print(f"bool(0): {bool(0)}")
print(f"bool(42): {bool(42)}")
print(f"bool(''): {bool('')}")
print(f"bool('Hello'): {bool('Hello')}")

→ Run this code interactively