⏳ Loading Python Engine...

📊 Day 01 : Data Types and Memory

🎯 Enterprise Objective

Mastering Python isn't just about knowing syntax; it's about understanding how data is fundamentally stored, accessed, and optimized in memory. Today, we deconstruct Python's 10 foundational data types. You will learn not only how to use them, but when to use them to write high-performance, production-grade analytical pipelines.

📋 Strategic Data Type Matrix

#TypeImmutable?Memory CostEnterprise Analytics Use Case
1int✅ YesVariablePrimary keys, absolute indexing, discrete counts.
2float✅ Yes24 bytesContinuous measurements, financial metrics, probabilities.
3complex✅ Yes32 bytesSignal processing, geospatial vectors, quantum modeling.
4str✅ YesVariableRaw text mining, log parsing, categorical identifiers.
5bool✅ Yes28 bytesBinary masks, conditional filtering, boolean logic.
6list❌ NoDynamicOrdered queues, chronological time-series buffers.
7tuple✅ YesFixedImmutable configuration matrices, compound dictionary keys.
8set❌ NoDynamicO(1) deduplication, cohort intersection/union analysis.
9dict❌ NoDynamicFast O(1) lookups, JSON payload structuring, aggregations.
10None✅ Yes16 bytesSingleton representation of missing/null values.

1. Integer (int) :

🔍 What is it?

An integer is a whole number that can be positive, negative, or zero, and it does not contain a decimal point. Unlike many other programming languages such as C or Java, Python integers support arbitrary precision, meaning they can grow to very large values limited only by your system's memory.

Examples: 10, -25, 0, 999999

x = 10**100  # A 101-digit number!
print(x)

💼 Why Data Analysts Care

Integers are the foundational blocks of tracking entities and loops.

Row Counts: Functions like len(df) return integers.

Primary Keys: Customer ID, Order ID, and Transaction ID are typically stored as integers for high-speed indexing.

Categorical Encoding: Converting string categories to integers (0 = Low, 1 = Medium, 2 = High) is a standard requirement for Machine Learning.

⚠️ Common Pitfall: Division Behavior

In Python, the standard division operator / always returns a float, even if the result is mathematically whole.

print(10 / 2)   # Output: 5.0 (float)
print(10 // 2)  # Output: 5 (int) - Use floor division to keep it an integer!
Important: Floor division truncates toward negative infinity (e.g., -7 // 2 yields -4).

🧠 Memory Insight

A standard Python integer uses about 28 bytes. For large-scale data processing (millions of rows), this is highly inefficient. Professional analysts use NumPy and pandas optimized types to compress data footprint.

Optimized TypeMemory UsageRange
int81 byte-128 to 127
int162 bytes-32K to 32K
int324 bytes~±2 billion
In [ ]:

🧪 Concept Checks: int

Q1. Create a = 15 and b = 4. Compute and print: a + b, a b, a // b, a % b, a * b. Verify each result's type with type().

In [ ]:

Q2. Write code that checks whether 2 ** 100 overflows. Print the result. How does Python handle arbitrarily large integers?

In [ ]:

Q3. Given x = 42, convert it to: float (float(x)), string (str(x)), and boolean (bool(x)). Print each result and its type.

In [ ]:

Q4. Write code to extract the tens digit from n = 4567 using integer arithmetic only (// and %). Expected: 6.

In [ ]:

Q5. Compute 10 // 3 and 10 / 3. Print both results and their types. Explain why // is called floor division.

In [ ]:

2. Float (float) : Decimal Numbers & Continuous Metrics

🔍 What is it?

A float represents continuous numerical data containing a decimal point or expressed in scientific e-notation. Python internally uses the 64-bit IEEE 754 double-precision standard, providing approximately 15-17 significant decimal digits of precision.

Examples: 3.14, -0.001, 2.5e2

pi = 3.1415926535
scientific = 2.5e3  # 2500.0

💼 Why Data Analysts Care

Floats are the absolute backbone of continuous modeling.

Financial Engineering: Tracking revenue, prices, and transaction amounts.

Statistical Modeling: Almost all analytical measures (Mean, Standard Deviation, Z-Scores) naturally evaluate to floats.

Geospatial Analytics: Latitude and longitude coordinates require deep decimal precision.

⚠️ Common Pitfall: The Floating-Point Trap

Because computers operate in base-2 (binary) fractions, they cannot perfectly represent all base-10 decimals. 0.1 + 0.2 will evaluate to 0.30000000000000004.

import math
print(math.isclose(0.1 + 0.2, 0.3))  # Output: True
Important: For strict financial accounting, avoid floats entirely and use Python's built-in decimal.Decimal module.

🧠 Special Float Values

Floats support unique architectural values critical for handling messy, real-world data:

  • float('nan'): The universal standard for missing data in Pandas.
  • float('inf'): Used to represent mathematical bounds.

In [ ]:

🧪 Concept Checks: float

Q1. Print 0.1 + 0.2. Is the result exactly 0.3? Write code using round() and math.isclose() to properly compare floats.

In [ ]:

Q2. Write code to convert temperature_f = 98.6 to Celsius using (f - 32) * 5/9. Print the result rounded to 2 decimal places.

In [ ]:

Q3. Create price = 19.99 and quantity = 3. Compute total = price * quantity. Why is the result not exactly 59.97? Fix it with round().

In [ ]:

Q4. Demonstrate float overflow: compute 1e308 * 2. What does Python return? Then try 1e-324 / 10. What happens with underflow?

In [ ]:

Q5. Use float('inf'), float('-inf'), and float('nan'). Test: inf > 1000000True, nan == nanFalse. Print all results.

In [ ]:

3. Complex (complex) : Multi-Dimensional Vectors

🔍 What is it?

A complex number consists of a real part and an imaginary part. Python natively supports them out of the box, using the j suffix (instead of i like in mathematics) to denote the imaginary unit.

Examples: 3+4j, -1j, 5.2+2j

z = 3 + 4j
print(z.real)  # Output: 3.0
print(z.imag)  # Output: 4.0

💼 Why Data Analysts Care

While rare in standard business intelligence, complex numbers are indispensable in specialized scientific fields.

Signal Processing: Using Fast Fourier Transforms (FFT) to analyze audio or sensor frequencies.

Electrical Engineering: Modeling alternating currents, phases, and impedance.

Vector Math: Instantly compute the magnitude (length) of the vector using the built-in abs() function.

⚠️ Common Pitfall: Comparison Operators

Complex numbers reside on a 2D plane. Therefore, they cannot be ordered sequentially using > or < like integers or floats.

# (3 + 4j) > (1 + 2j)  <-- Raises TypeError!
print((3 + 4j) == (3 + 4j))  # You can only check for equality
Important: You cannot convert a complex number to an int or a float using int() or float(). You must explicitly extract the .real part.

🧠 Memory Insight

Because a complex number stores two double-precision floats under the hood, it consumes more memory (32 bytes). In large-scale computing, NumPy handles arrays of complex numbers using highly optimized complex64 or complex128 types.

In [ ]:

🧪 Concept Checks: complex

Q1. Create z = 3 + 4j. Print its .real, .imag, and compute the magnitude using abs(z). Verify: sqrt(3² + 4²) = 5.

In [ ]:

Q2. Add (2 + 3j) and (4 - 1j). Print the result. Then multiply them and print. Show complex arithmetic works naturally.

In [ ]:

Q3. Write code to check if type(5j) is complex. Then check if isinstance(5j, (int, float, complex)) returns True.

In [ ]:

Q4. Convert the integer 7 to a complex number using complex(7). What is its imaginary part? Print complex(3, 4) and verify.

In [ ]:

Q5. Try complex('3+4j') (string parsing). Then try complex('3 + 4j') with spaces — does it work? Show the error handling.

In [ ]:

4. String (str) : Unstructured Text Data

🔍 What is it?

A string is an ordered, immutable sequence of Unicode characters. It is used to represent any textual data and can be defined using single, double, or triple quotes for multi-line text.

Examples: "Alice", 'New York', '''Multi-line text'''

greeting = "Hello, World!"
print(greeting[0])  # Output: 'H'

💼 Why Data Analysts Care

A vast majority of raw data exists as unstructured text. Analysts spend up to 80% of their time cleaning it.

Categorical Features: Representing non-numerical dimensions (e.g., Region, Product_Tier).

Log Parsing: Extracting precise metadata (timestamps, IPs, error codes) from raw server logs.

Dynamic Reporting: Using f-strings to seamlessly inject variables directly into dashboard strings.

⚠️ Common Pitfall: Immutability

Strings are immutable. Once created, they cannot be modified in-place. Every operation (like .replace() or .upper()) creates a brand new string object in RAM.

s = "cat"
# s[0] = "b"  <-- Raises TypeError!
s = "b" + s[1:]  # Correct way: reassign to a new string
Important: Chaining methods like data.strip().lower().replace('x', 'y') is clean but computationally expensive on millions of rows because it generates multiple temporary strings.

🧠 Memory Insight: String Interning

Python optimizes memory by "interning" short, identifier-like strings. If multiple variables are assigned "revenue", Python stores the word "revenue" only once in RAM. This makes dictionary key lookups blazing fast via O(1) pointer comparison.

In [ ]:

🧪 Concept Checks: str

Q1. Create a multi-line string using triple quotes. Print it. Then create the same using \n. Verify both produce identical output.

In [ ]:

Q2. Given name = 'alice', chain .strip().title() and print. Then use an f-string: f'{name.title()} has {len(name)} letters'.

In [ ]:

Q3. Write code to check if 'Python' contains 'tho' using the in operator. Then use .find() and .index(). Show what happens with .index() when not found.

In [ ]:

Q4. Demonstrate string immutability: try s = 'hello'; s[0] = 'H'. Catch the error. Show the correct way: s = 'H' + s[1:].

In [ ]:

Q5. Given data = ' Alice, 30, NYC ', split by comma, strip each part, and print as a clean list: ['Alice', '30', 'NYC'].

In [ ]:

5. Boolean (bool) : Binary Logic & Masks

🔍 What is it?

A boolean represents exactly one of two binary states: True or False. Under the hood, Python's bool is a strict subclass of the integer type (True evaluates to 1, and False evaluates to 0).

Examples: True, False

is_active = True
print(type(is_active))  # Output: <class 'bool'>

💼 Why Data Analysts Care

Booleans are the fundamental building blocks of dataset filtering and conditional flow.

Boolean Masking: Filtering Pandas datasets using boolean arrays (e.g., df[df['salary'] > 100000]).

State Flags: Tracking binary conditions (has_purchased, is_churned).

Instant Aggregations: Because True = 1, you can instantly count matches by summing a boolean array (sum([True, False, True]) yields 2).

⚠️ Common Pitfall: Truthy vs Falsy

Python evaluates objects in conditional statements based on their "Truthiness". Empty structures are strictly evaluated as Falsy (e.g., 0, 0.0, '', [], {}, None).

my_list = []
if not my_list:
    print("This evaluates because the list is Falsy!")
Important: A string containing a single space " " or the literal text "False" is Truthy because the string is technically not empty!

🧠 The Logical Short-Circuit

Python's logical operators (and, or) use short-circuit evaluation for maximum performance. In A and B, if A is False, Python stops instantly without ever evaluating B. Always place your most computationally expensive checks on the right side!

In [ ]:

🧪 Concept Checks: bool

Q1. Test truthiness of: bool(0), bool(''), bool([]), bool(None), bool(0.0). Print each. Then test: bool(1), bool('hello'), bool([1]). What pattern do you see?

In [ ]:

Q2. Write code: x = 10; print(x > 5 and x < 20). Then use chained comparison: print(5 < x < 20). Verify both give the same result.

In [ ]:

Q3. Demonstrate True == 1 and False == 0. Then show: True + True + True3. Explain why booleans are integers in Python.

In [ ]:

Q4. Write a one-liner using bool() to check if a list items = [1, 2, 3] is non-empty. Then check an empty list. Explain why if items: works.

In [ ]:

Q5. Use any() and all() on [True, False, True]. Print both. Then test on [0, '', None] and [1, 'a', [1]]. Explain the results.

In [ ]:

6. NoneType (None) : The Null State

🔍 What is it?

The NoneType is a special data type that has exactly one valid value: None. It is Python's native way to represent the absolute absence of a value, null, or "nothing". It is not equal to 0, False, or an empty string.

Examples: None

missing_value = None
print(type(missing_value))  # Output: <class 'NoneType'>

💼 Why Data Analysts Care

None is critical for handling incomplete, corrupt, or uninitialized data states.

Missing Data: Before data reaches a Pandas DataFrame (where it becomes NaN), raw Python handles missing records securely as None.

Safe Default Arguments: Used natively to initialize optional parameters in custom analytical functions without triggering memory leaks.

API Nulls: When reading from a SQL database or a JSON API, NULL values are automatically translated into Python None objects.

⚠️ Common Pitfall: The Mutable Default Argument Trap

A catastrophic error in Python is using a mutable type (like a list or dict) as a default argument in a function. The list will persist across all function calls!

# CORRECT WAY: Use None to initialize!
def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket
Important: None

🧠 Memory Insight: The Singleton Pattern

None is a strict memory singleton. There is only ever one instance of None existing in your computer's RAM at any given time. Because of this, you must always check for None using the identity operator is (e.g., if val is None:) instead of the equality operator ==. This validates the strict memory address and prevents accidental truthy/falsy evaluation errors.
In [ ]:

🧪 Concept Checks: None

Q1. Write a function find_item(lst, target) that returns the index if found, None if not. Call it and check the result with is None (not == None).

In [ ]:

Q2. Show that None is a singleton: a = None; b = None; print(a is b)True. Explain why is is preferred over == for None checks.

In [ ]:

Q3. Create a list [1, None, 3, None, 5]. Write code to filter out None values using a list comprehension with is not None. Print the clean list.

In [ ]:

Q4. Demonstrate None as a default parameter: def greet(name=None): return f'Hello, {name or "World"}'. Test with and without argument.

In [ ]:

Q5. Check the boolean value of None: bool(None)False. Write an if statement that handles None, 0, and '' differently from each other.

In [ ]:

7. List (list) : Dynamic & Mutable Sequences

🔍 What is it?

A list is an ordered, mutable collection of arbitrary objects created using square brackets []. Python lists are dynamic arrays of memory pointers—they can grow or shrink on demand and hold mixed data types simultaneously.

Examples: [1, 2, 3], ['Alice', 30, True]

users = ["Alice", "Bob"]
users.append("Charlie")  # Grows dynamically in-place
print(users)

💼 Why Data Analysts Care

Lists are the most versatile structure for holding sequenced data.

Time-Series Buffers: Sequentially appending streaming data chronologically.

Schema Definitions: Passing ordered column names into DataFrame operations.

Batch Aggregations: Accumulating results dynamically during loops or list comprehensions ([x**2 for x in data]).

⚠️ Common Pitfall: The Shallow Copy Trap

Because lists are mutable, assigning a list to a new variable creates a memory reference, not an independent copy. Altering the new list will permanently corrupt the original list!

list_a = [1, 2, 3]
list_b = list_a      # Points to the exact same memory address!
list_b.append(4)     # Corrupts list_a as well
Important: Always safely duplicate a list using .copy() or slicing [:]. Furthermore, never remove items from a list while actively looping over it via a for loop.

🧠 Performance Insight (Big-O Bottleneck)

Lists are highly inefficient for large-scale searching and numerical math. Checking x in my_list executes in O(N) time (Python scans elements one-by-one). For heavy math, switch to NumPy arrays. For fast lookups, convert to a Set.

In [ ]:

🧪 Concept Checks: list

Q1. Create nums = [5, 2, 8, 1, 9]. Use .sort(), .reverse(), .append(6), .pop(), .insert(0, 10). Print after each operation.

In [ ]:

Q2. Demonstrate list mutability: a = [1, 2, 3]; b = a; b.append(4). Print both a and b. Why did a change? Fix it with b = a.copy().

In [ ]:

Q3. Write code to access: first element, last element, slice [1:3], every 2nd element [::2], and reversed [::-1] from [10,20,30,40,50].

In [ ]:

Q4. Create a nested list matrix = [[1,2],[3,4],[5,6]]. Access element 4 using double indexing. Flatten it to [1,2,3,4,5,6] using a loop.

In [ ]:

Q5. Given words = ['hello','world'], show that words * 3 repeats the list and words + ['python'] concatenates. Print both results.

In [ ]:

8. Tuple (tuple) : Immutable Records

🔍 What is it?

A tuple is an ordered, immutable sequence of elements created using parentheses (). Because tuples cannot be changed after creation, Python allocates exact, fixed memory blocks for them, making them highly secure and slightly faster than lists.

Examples: (10, 20), ('red', 'green', 'blue')

coordinates = (40.7128, -74.0060)
print(coordinates[0])  # Output: 40.7128

💼 Why Data Analysts Care

Tuples store fixed, heterogeneous records where the position of the data has strict meaning.

Data Integrity: Safeguarding static reference data (like RGB constants, database connection URLs) from accidental mutation.

Compound Dictionary Keys: Because tuples are immutable (hashable), they can be used to construct multi-dimensional dictionary keys (which lists cannot do).

Function Returns: Seamlessly packing and unpacking multiple return values (clicks, impressions = get_metrics()).

⚠️ Common Pitfall: Single-Element Tuples

A common mistake when creating a tuple with exactly one element is forgetting the trailing comma.

t1 = (5)   # This is just an integer in parentheses!
t2 = (5,)  # This is a valid single-element tuple
Important: Tuple immutability only applies to the tuple structure itself. If a tuple contains a mutable object (like a list), the contents of that list can still be modified!

🧠 Memory Insight

Tuples instantiate faster and consume slightly less memory than lists because they lack dynamic resizing overhead. A list pre-allocates extra memory blocks to allow for fast .append() operations, whereas a tuple allocates exactly the memory it needs.

In [ ]:

🧪 Concept Checks: tuple

Q1. Create point = (3, 4). Unpack into x, y. Compute distance from origin: (x2 + y2) ** 0.5. Print the result.

In [ ]:

Q2. Try point[0] = 10. Catch the TypeError. Then show that a tuple containing a list t = (1, [2,3]) allows t[1].append(4). Explain why.

In [ ]:

Q3. Use tuple unpacking with : first, middle, last = (1, 2, 3, 4, 5). Print each variable. What type is middle?

In [ ]:

Q4. Create a single-element tuple: t = (42,). Show that t = (42) without the comma is just an integer. Print type() of both.

In [ ]:

Q5. Use a tuple as a dictionary key: locations = {(40.7, -74.0): 'NYC'}. Try the same with a list as key. Show the TypeError.

In [ ]:

9. Set (set) : O(1) Unique Collections

🔍 What is it?

A set is an unordered, mutable collection of strictly unique elements. Sets are backed by highly optimized Hash Tables in C, sacrificing element ordering to provide lightning-fast mathematical operations and lookups.

Examples: {1, 2, 3}, {'apple', 'banana'}

unique_ids = {101, 102, 103, 101}
print(unique_ids)  # Duplicates automatically dropped! Output: {101, 102, 103}

💼 Why Data Analysts Care

Sets are the ultimate tool for rapid cohort comparisons and pipeline deduplication.

Instant Deduplication: Instantly stripping duplicate values from massive, messy arrays (list(set(raw_data))).

Cohort Analysis: Rapidly computing intersections (users active in both Q1 and Q2) and unions.

Security & Filtering: Validating IDs against a blacklist in constant time.

⚠️ Common Pitfall: Unhashable Elements

Sets can only store immutable (hashable) objects. You cannot place a list or a dictionary inside a set.

# invalid_set = { [1, 2], [3, 4] }  <-- Raises TypeError!
valid_set = { (1, 2), (3, 4) }      # Tuples are hashable!
Important: You cannot create an empty set using {} (that creates an empty dictionary). You must explicitly call set().

🧠 Performance Insight: O(1) Lookups

Checking membership (x in my_set) executes in O(1) constant time. Python passes the value into a mathematical hash function, instantly calculating its exact location in RAM. It takes the exact same amount of time to find an ID in a set of 10 items as it does in a set of 10 million items!

In [ ]:

🧪 Concept Checks: set

Q1. Create a = {1,2,3,4} and b = {3,4,5,6}. Compute and print: union (|), intersection (&), difference (-), symmetric difference (^).

In [ ]:

Q2. Given names = ['Alice','Bob','Alice','Charlie','Bob'], convert to a set to get unique names. Convert back to sorted list. Print the result.

In [ ]:

Q3. Demonstrate set's O(1) lookup: check 'Alice' in large_set vs 'Alice' in large_list for a 100K-element collection. Time both.

In [ ]:

Q4. Create a frozenset from {1,2,3}. Try .add(4). Show the error. Use frozenset as a dict key — prove it works unlike regular sets.

In [ ]:

Q5. Write code to find common elements between 3 sets using chained &. Test: {1,2,3} & {2,3,4} & {3,4,5}{3}.

In [ ]:

10. Dictionary (dict) : High-Speed Key-Value Stores

🔍 What is it?

A dictionary is a mutable, ordered collection of key-value pairs. Like sets, dictionaries are powered by highly optimized Hash Tables. Keys must be strictly unique and immutable, while values can be absolutely any object.

Examples: {'name': 'Alice', 'age': 30}

employee = {
    "id": 1042,
    "role": "Data Analyst",
    "skills": ["Python", "SQL"]
}
print(employee["role"])  # Output: 'Data Analyst'

💼 Why Data Analysts Care

Dictionaries are the architectural backbone of structured data transfer and aggregation in Python.

JSON & API Ingestion: Dictionaries map perfectly to JSON format, making them the default structure for ingesting web API payloads.

In-Memory Lookups: Simulating rapid-access relational lookups without the overhead of spinning up a full SQL database.

Frequency Counters: Rapidly tallying categorical occurrences (e.g., word frequencies, error codes).

⚠️ Common Pitfall: The KeyError Crash

Accessing a missing key via strict bracket notation will immediately crash your script, bringing down entire data pipelines.

emp = {"name": "Alice"}
# print(emp["salary"])  <-- Raises KeyError!
print(emp.get("salary", 0))  # Professional standard: Safely returns 0
Important: When iterating natively (for item in my_dict:), Python only yields the keys. To iterate over both, use for k, v in my_dict.items():.

🧠 The Dictionary Hash Table

Dictionaries provide O(1) lookups for keys. When you query emp["skills"], Python hashes the string "skills" to calculate the exact memory bucket where the value is stored, making mapping operations blazingly fast.

In [ ]:

🧪 Concept Checks: dict

Q1. Create emp = {'name':'Alice', 'dept':'Eng', 'salary':85000}. Access using [] and .get(). Show [] raises KeyError for missing keys but .get() returns None.

In [ ]:

Q2. Iterate over a dict three ways: .keys(), .values(), .items(). Print each. Use .items() in a formatted f-string loop.

In [ ]:

Q3. Merge two dicts: d1 = {'a':1, 'b':2} and d2 = {'b':3, 'c':4} using {d1, d2}. Print result. Which value wins for key 'b'?

In [ ]:

Q4. Use .setdefault() to build a frequency counter: loop through 'banana', using d.setdefault(char, 0) then incrementing. Print the dict.

In [ ]:

Q5. Create a dict comprehension: {x: x**2 for x in range(1, 6)}. Then filter: keep only entries where value > 10. Print both.

In [ ]:

🛠️ Professional Practice Tasks

Theory is useless without muscle memory. Complete these tasks to solidify your understanding.

Task 1 (Type Inspector): Write a function inspect(value) that prints: the value, type(), isinstance() checks against int/float/str/bool/list/dict, truthiness (bool()), and sys.getsizeof(). Test with 6 different types.

In [ ]:

Task 2 (Type Converter): Write a function smart_convert(value) that takes a string and returns: int if it's a whole number, float if decimal, bool if 'true'/'false', None if 'none'/empty, else the original string. Test with 8 inputs.

In [ ]:

Task 3 (Data Record): Build a complete record using ALL types: {'id':1, 'name':'Alice', 'salary':85000.50, 'is_active':True, 'skills':['Python','SQL'], 'scores':(90,85,92), 'tags':{'senior','lead'}, 'manager':None}. Access and print each field with its type.

In [ ]:

Task 4 (Mutable vs Immutable Lab): Write experiments proving: strings, tuples, ints are immutable (show id changes on 'modification'). Lists, dicts, sets are mutable (show id stays same). Print id() before and after each operation.

In [ ]:

Task 5 (Type Gotchas): Demonstrate 5 common type pitfalls: (1) 0.1+0.2!=0.3, (2) mutable default args, (3) is vs == for ints >256, (4) list * with nested refs, (5) dict key with unhashable type. Print each gotcha with explanation.

In [ ]:

💻 Pure Coding Interview Questions

Q1.

Write a function type_of(value) that returns a human-readable type name: type_of(42)'integer', type_of([1])'list'. Handle all built-in types.

In [ ]:

Q2.

Write code that proves Python integers have unlimited precision: compute 2**1000 and print the number of digits. Compare with other languages.

In [ ]:

Q3.

Write a function safe_cast(value, target_type, default=None) that safely converts between types, returning default on failure.

In [ ]:

Q4.

Write a function deep_type_check(obj) that recursively reports types in nested structures: {'a': [1, 'hello', (True, None)]} → full type tree.

In [ ]:

Q5.

Write code demonstrating that True + True = 2 and False * 10 = 0. Use this to count True values in a list using sum().

In [ ]:

Q6.

Write a function flatten_types(lst) that takes a mixed list [1, 'a', [2, [3]], (4,)] and returns a flat list of all atomic values with their types.

In [ ]:

Q7.

Write a function is_numeric(value) that returns True for int, float, complex, and numeric strings like '42', '3.14', '2+3j'. Handle edge cases.

In [ ]:

Q8.

Write code showing the difference between == and is for: small ints (cached), large ints, strings (interned), lists, and None.

In [ ]:

Q9.

Write a function coerce_types(a, b) that returns both values cast to the 'wider' type: int+float→float, float+complex→complex, any+str→str.

In [ ]:

Q10.

Write a function dict_to_namedtuple(name, d) that converts a dict to a namedtuple. Test with {'x':1, 'y':2}Point(x=1, y=2).

In [ ]:

Q11.

Write a function memory_report(*values) that prints each value, its type, and sys.getsizeof(). Compare: int, float, str, list, tuple, dict, set.

In [ ]:

Q12.

Write a function validate_record(record, schema) where schema is {'name': str, 'age': int, 'active': bool}. Return list of type mismatches.

In [ ]:

Q13.

Write code that creates all falsy values in Python: 0, 0.0, 0j, '', [], (), {}, set(), None, False. Verify each with bool(). Then find a surprising truthy value.

In [ ]:

Q14.

Write a function serialize(obj) that converts any Python object to a JSON-compatible type: sets→lists, tuples→lists, None→null. Handle nested structures.

In [ ]:

Q15.

Write a function find_type_mismatches(list1, list2) that compares two lists element-by-element and reports positions where types differ.

In [ ]:

Q16.

Write a function create_matrix(rows, cols, fill=0) that creates a 2D list correctly (no shallow copy trap). Demonstrate the trap with [[0]cols]rows.

In [ ]:

Q17.

Write a function dict_diff(d1, d2) that returns: keys only in d1, only in d2, in both with same values, in both with different values.

In [ ]:

Q18.

Write a function type_histogram(data) that counts occurrences of each type in a mixed list. Return {'int': 3, 'str': 2, 'float': 1}.

In [ ]:

Q19.

Write code showing that tuples are hashable but lists are not. Create a dict mapping tuple-keys to values. Show the error with list-keys.

In [ ]:

Q20.

Write a function smart_equals(a, b) that compares with type awareness: smart_equals(1, 1.0)True but smart_equals(1, '1')False.

In [ ]:

Q21.

Write a function deep_freeze(obj) that recursively converts mutable types to immutable: lists→tuples, sets→frozensets, dicts→frozenset of tuples.

In [ ]:

Q22.

Write a function type_coercion_chain(value, *types) that tries casting value through each type in sequence: type_coercion_chain('42.5', int, float)42.5.

In [ ]:

Q23.

Write code that demonstrates string interning: a = 'hello'; b = 'hello'; print(a is b). Then try with a = 'hello world'. Explain the difference.

In [ ]:

Q24.

Write a function build_schema(sample_data) that infers a schema from a list of dicts: {'name': 'str', 'age': 'int', 'scores': 'list'}. Handle inconsistent types.

In [ ]:

Q25.

Write a function type_safe_merge(*dicts) that merges dicts but raises TypeError if the same key has different types across dicts.

In [ ]:

📊 Day 1 Executive Summary

#TypeFocus AreaProfessional Application
1intTopic 1Absolute counts, primary IDs
2floatTopic 2Metrics, continuous variables
3complexTopic 3Scientific computing
4strTopic 4Text parsing, categorical data
5boolTopic 5Logic gating, boolean masks
6listTopic 6Ordered, mutable data streams
7tupleTopic 7Immutable constraints, fast read
8setTopic 8O(1) deduplication, set theory
9dictTopic 9Fast lookups, unstructured rows
10NoneTopic 10Explicit null-value handling

✅ Instructor's End-of-Day Checklist

• [ ] I deeply understand the difference between mutable and immutable types.

• [ ] I know why evaluating set membership is faster than list membership.

• [ ] I understand the relationship between bool and int.

• [ ] I can safely handle NoneType values to prevent runtime errors.

• [ ] I have successfully completed all 5 practice tasks.

• [ ] I have reviewed and internalized all 25 interview questions.