0dfg-bit

Python Advanced Concepts

Advanced Python Techniques

This page focuses on intermediate to advanced Python concepts for developers who already understand the basics. We'll explore more complex programming patterns, libraries, and applications.

Decorators

Decorators are a powerful way to modify or enhance functions without changing their code.

# A simple decorator
def timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"Function {func.__name__} took {end-start:.2f} seconds to run")
        return result
    return wrapper

@timer
def slow_function():
    import time
    time.sleep(1)
    print("Function executed")

# Usage
slow_function()  # Will print execution time

Context Managers

Context managers allow you to allocate and release resources precisely when you want to.

# Custom context manager
class ManagedFile:
    def __init__(self, filename):
        self.filename = filename
        
    def __enter__(self):
        self.file = open(self.filename, 'w')
        return self.file
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
            
# Usage
with ManagedFile('test.txt') as f:
    f.write('Hello, world!')
    
# File is automatically closed after the block

Generators and Iterators

Generators provide an elegant way to create iterators that can process large datasets efficiently.

# Generator function to create a Fibonacci sequence
def fibonacci(n):
    a, b = 0, 1
    count = 0
    while count < n:
        yield a
        a, b = b, a + b
        count += 1

# Using the generator
for num in fibonacci(10):
    print(num)
    
# Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Data Analysis with Pandas

Pandas is a powerful library for data manipulation and analysis.

import pandas as pd
import numpy as np

# Create a DataFrame
df = pd.DataFrame({
    'A': np.random.rand(5),
    'B': np.random.rand(5),
    'C': np.random.rand(5)
})

# Data manipulation
df['D'] = df['A'] + df['B']
filtered = df[df['D'] > 1]

# Group operations
grouped = df.groupby('C').mean()

# Time series
dates = pd.date_range('20230101', periods=5)
ts = pd.Series(np.random.randn(5), index=dates)
monthly = ts.resample('M').mean()

Web Scraping with Beautiful Soup

Beautiful Soup is a library for parsing HTML and XML documents, commonly used for web scraping.

import requests
from bs4 import BeautifulSoup

# Fetch a webpage
url = 'https://example.com'
response = requests.get(url)
html = response.text

# Parse the HTML
soup = BeautifulSoup(html, 'html.parser')

# Find elements
title = soup.title.text
headings = soup.find_all('h2')
links = soup.find_all('a', href=True)

# Extract data
for link in links:
    print(f"Link: {link.text} -> {link['href']}")

# Navigate the DOM
main_content = soup.find('div', {'id': 'main'})
paragraphs = main_content.find_all('p') if main_content else []

Multithreading and Multiprocessing

Python provides several ways to achieve concurrency and parallelism.

import threading
import multiprocessing
import time

# Function to be executed in parallel
def worker(num):
    print(f"Worker {num} started")
    time.sleep(1)
    print(f"Worker {num} finished")

# Using threads
def run_threads():
    threads = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(i,))
        threads.append(t)
        t.start()
    
    for t in threads:
        t.join()

# Using processes
def run_processes():
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()
    
    for p in processes:
        p.join()

# Run with threads (good for I/O-bound tasks)
run_threads()

# Run with processes (good for CPU-bound tasks)
run_processes()

Building REST APIs with FastAPI

FastAPI is a modern, fast web framework for building APIs with Python.

from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI()

# Data model
class Item(BaseModel):
    id: Optional[int] = None
    name: str
    description: Optional[str] = None
    price: float

# In-memory database
items_db = {}
counter = 0

# CRUD operations
@app.post("/items/", response_model=Item)
def create_item(item: Item):
    global counter
    counter += 1
    item.id = counter
    items_db[counter] = item
    return item

@app.get("/items/", response_model=List[Item])
def read_items(skip: int = 0, limit: int = 10):
    return list(items_db.values())[skip : skip + limit]

@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
    if item_id not in items_db:
        raise HTTPException(status_code=404, detail="Item not found")
    return items_db[item_id]

@app.put("/items  detail="Item not found")
    return items_db[item_id]

@app.put("/items/{item_id}", response_model=Item)
def update_item(item_id: int, item: Item):
    if item_id not in items_db:
        raise HTTPException(status_code=404, detail="Item not found")
    item.id = item_id
    items_db[item_id] = item
    return item

@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    if item_id not in items_db:
        raise HTTPException(status_code=404, detail="Item not found")
    del items_db[item_id]
    return {"message": "Item deleted"}

Machine Learning with Scikit-learn

Scikit-learn is a simple and efficient tool for data mining and data analysis.

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
import numpy as np

# Load dataset
iris = load_iris()
X, y = iris.data, iris.target

# Split data
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# Create and train model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Make predictions
y_pred = model.predict(X_test)

# Evaluate model
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred, target_names=iris.target_names)

print(f"Accuracy: {accuracy:.2f}")
print("Classification Report:")
print(report)

# Feature importance
feature_importance = model.feature_importances_
for i, importance in enumerate(feature_importance):
    print(f"Feature {iris.feature_names[i]}: {importance:.4f}")