python

examples

examples.py🐍
"""
11 - Advanced Data Handling: Examples
Run this file to see advanced data concepts in action!
"""

print("=" * 60)
print("ADVANCED DATA HANDLING - EXAMPLES")
print("=" * 60)

import copy
import sys
from collections import Counter, defaultdict, namedtuple, deque, OrderedDict, ChainMap

# =============================================================================
# 1. SHALLOW VS DEEP COPY
# =============================================================================
print("\n--- 1. Shallow vs Deep Copy ---\n")

# Reference (NOT a copy)
original = [1, 2, [3, 4]]
reference = original
reference[0] = 100
print(f"Reference changes affect original: {original}")

# Reset
original = [1, 2, [3, 4]]

# Shallow copy
shallow = original.copy()  # or original[:] or list(original)
shallow[0] = 100
print(f"Shallow copy - outer change: original = {original}")  # unchanged

shallow[2][0] = 999
print(f"Shallow copy - inner change: original = {original}")  # changed!

# Deep copy
original = [1, 2, [3, 4, [5, 6]]]
deep = copy.deepcopy(original)
deep[2][2][0] = 999
print(f"Deep copy - any level change: original = {original}")  # unchanged!
print(f"Deep copy: {deep}")

# =============================================================================
# 2. MEMORY AND REFERENCES
# =============================================================================
print("\n--- 2. Memory and References ---\n")

a = [1, 2, 3]
b = a           # Same object
c = [1, 2, 3]   # Different object

print(f"id(a): {id(a)}")
print(f"id(b): {id(b)}")
print(f"id(c): {id(c)}")
print(f"a is b: {a is b}")   # True
print(f"a is c: {a is c}")   # False
print(f"a == c: {a == c}")   # True

# String interning
s1 = "hello"
s2 = "hello"
print(f"\nString interning: 'hello' is 'hello': {s1 is s2}")

# =============================================================================
# 3. COUNTER
# =============================================================================
print("\n--- 3. Counter ---\n")

# Count word frequencies
text = "apple banana apple cherry banana apple"
words = text.split()
counter = Counter(words)

print(f"Counter: {counter}")
print(f"Most common 2: {counter.most_common(2)}")
print(f"Count of 'apple': {counter['apple']}")

# Counter arithmetic
c1 = Counter("aab")
c2 = Counter("abc")
print(f"\nCounter('aab') + Counter('abc'): {c1 + c2}")
print(f"Counter('aab') - Counter('abc'): {c1 - c2}")

# =============================================================================
# 4. DEFAULTDICT
# =============================================================================
print("\n--- 4. defaultdict ---\n")

# Group items by first letter
words = ['apple', 'banana', 'avocado', 'berry', 'cherry', 'apricot']

# Without defaultdict (verbose)
groups_manual = {}
for word in words:
    key = word[0]
    if key not in groups_manual:
        groups_manual[key] = []
    groups_manual[key].append(word)

# With defaultdict (clean)
groups = defaultdict(list)
for word in words:
    groups[word[0]].append(word)

print(f"Grouped by first letter: {dict(groups)}")

# Count occurrences
counts = defaultdict(int)
for word in words:
    counts[word[0]] += 1
print(f"Counts by first letter: {dict(counts)}")

# =============================================================================
# 5. NAMEDTUPLE
# =============================================================================
print("\n--- 5. namedtuple ---\n")

Point = namedtuple('Point', ['x', 'y'])
Person = namedtuple('Person', 'name age city')

p = Point(3, 4)
person = Person('Alice', 25, 'NYC')

print(f"Point: {p}")
print(f"Point.x: {p.x}, Point.y: {p.y}")
print(f"Point as dict: {p._asdict()}")

print(f"\nPerson: {person}")
print(f"Person.name: {person.name}")

# Create from dict
data = {'x': 10, 'y': 20}
p2 = Point(**data)
print(f"Point from dict: {p2}")

# =============================================================================
# 6. DEQUE
# =============================================================================
print("\n--- 6. deque (Double-Ended Queue) ---\n")

dq = deque([1, 2, 3])
print(f"Initial: {dq}")

dq.append(4)
print(f"After append(4): {dq}")

dq.appendleft(0)
print(f"After appendleft(0): {dq}")

dq.pop()
print(f"After pop(): {dq}")

dq.popleft()
print(f"After popleft(): {dq}")

# Rotate
dq = deque([1, 2, 3, 4, 5])
dq.rotate(2)
print(f"After rotate(2): {dq}")

# Fixed size
dq = deque(maxlen=3)
for i in range(5):
    dq.append(i)
print(f"maxlen=3 after appending 0-4: {dq}")

# =============================================================================
# 7. ORDEREDDICT
# =============================================================================
print("\n--- 7. OrderedDict ---\n")

od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3
print(f"OrderedDict: {od}")

od.move_to_end('a')
print(f"After move_to_end('a'): {od}")

od.move_to_end('c', last=False)
print(f"After move_to_end('c', last=False): {od}")

# =============================================================================
# 8. CHAINMAP
# =============================================================================
print("\n--- 8. ChainMap ---\n")

defaults = {'color': 'red', 'size': 'medium', 'theme': 'light'}
user_settings = {'color': 'blue'}

combined = ChainMap(user_settings, defaults)
print(f"ChainMap: {dict(combined)}")
print(f"color (from user): {combined['color']}")
print(f"size (from defaults): {combined['size']}")

# =============================================================================
# 9. MEMORY EFFICIENCY
# =============================================================================
print("\n--- 9. Memory Efficiency ---\n")

list_data = [1, 2, 3, 4, 5]
tuple_data = (1, 2, 3, 4, 5)

print(f"List size: {sys.getsizeof(list_data)} bytes")
print(f"Tuple size: {sys.getsizeof(tuple_data)} bytes")
print("Tuples are more memory efficient!")

# Generator vs list
list_comp = [x**2 for x in range(1000)]
gen_expr = (x**2 for x in range(1000))

print(f"\nList comprehension size: {sys.getsizeof(list_comp)} bytes")
print(f"Generator expression size: {sys.getsizeof(gen_expr)} bytes")

# =============================================================================
# 10. SET FOR FAST LOOKUP
# =============================================================================
print("\n--- 10. Set for Fast Lookup ---\n")

import time

data = list(range(100000))
data_set = set(data)

# List lookup
start = time.time()
for _ in range(1000):
    99999 in data
list_time = time.time() - start

# Set lookup
start = time.time()
for _ in range(1000):
    99999 in data_set
set_time = time.time() - start

print(f"List lookup time: {list_time:.4f}s")
print(f"Set lookup time: {set_time:.4f}s")
print(f"Set is {list_time/set_time:.0f}x faster!")

# =============================================================================
# 11. DATA CLASSES
# =============================================================================
print("\n--- 11. Data Classes ---\n")

from dataclasses import dataclass, field
from typing import List

@dataclass
class Student:
    name: str
    age: int
    grades: List[int] = field(default_factory=list)
    
    def average(self):
        return sum(self.grades) / len(self.grades) if self.grades else 0

s1 = Student("Alice", 20, [85, 90, 88])
s2 = Student("Bob", 21)

print(f"Student: {s1}")
print(f"Average: {s1.average()}")
print(f"Student without grades: {s2}")

# Automatic equality
s3 = Student("Alice", 20, [85, 90, 88])
print(f"s1 == s3: {s1 == s3}")

# Frozen (immutable) dataclass
@dataclass(frozen=True)
class Point:
    x: float
    y: float

p = Point(3.0, 4.0)
print(f"Frozen Point: {p}")
# p.x = 5  # Would raise FrozenInstanceError

# =============================================================================
# 12. TYPE HINTS
# =============================================================================
print("\n--- 12. Type Hints ---\n")

from typing import Optional, Union, Dict, Callable

def greet(name: str) -> str:
    return f"Hello, {name}"

def process(items: List[int]) -> Dict[str, int]:
    return {"sum": sum(items), "count": len(items)}

def find_user(user_id: int) -> Optional[str]:
    users = {1: "Alice", 2: "Bob"}
    return users.get(user_id)

def apply_func(func: Callable[[int], int], value: int) -> int:
    return func(value)

print(f"greet('World'): {greet('World')}")
print(f"process([1,2,3]): {process([1, 2, 3])}")
print(f"find_user(1): {find_user(1)}")
print(f"find_user(999): {find_user(999)}")
print(f"apply_func(lambda x: x*2, 5): {apply_func(lambda x: x*2, 5)}")

# =============================================================================
# 13. PRACTICAL EXAMPLE - WORD FREQUENCY
# =============================================================================
print("\n--- 13. Practical: Word Frequency Analysis ---\n")

text = """
Python is a programming language. Python is easy to learn.
Learning Python is fun. Python has many libraries.
"""

# Using Counter
words = text.lower().split()
word_count = Counter(words)

print("Top 5 words:")
for word, count in word_count.most_common(5):
    print(f"  '{word}': {count}")

# Using defaultdict to group by length
by_length = defaultdict(list)
for word in set(words):
    by_length[len(word)].append(word)

print("\nWords by length:")
for length in sorted(by_length.keys()):
    print(f"  {length} chars: {by_length[length]}")

print("\n" + "=" * 60)
print("END OF EXAMPLES")
print("=" * 60)
Examples - Python Tutorial | DeepML