THỰC HÀNH TỔNG HỢP 4 - LẬP TRÌNH NÂNG CAO¶
I. Mục tiêu buổi học¶
Mục tiêu chính¶
Buổi học này nhằm củng cố và thực hành kiến thức từ Buổi 16-18, tập trung vào:
- Functions (Hàm) - Tổ chức code hiệu quả
- Error Handling - Xử lý ngoại lệ chuyên nghiệp
- Modules và Packages - Quản lý dự án lớn
- Code Architecture - Thiết kế phần mềm tốt
Kỹ năng đạt được¶
Sau buổi học, học viên sẽ có khả năng:
- Viết code chuyên nghiệp với function design tốt
- Xử lý errors một cách robust và user-friendly
- Tổ chức project với modules và packages
- Apply best practices trong software development
II. Cấu trúc buổi học (90 phút)¶
Hoạt động | Thời gian | Nội dung |
---|---|---|
Code Architecture Review | 20 phút | Best practices & design patterns |
Advanced Functions | 30 phút | Decorators, lambda, advanced concepts |
Project Development | 30 phút | Mini framework development |
Code Review & Optimization | 10 phút | Professional code review |
III. Code Architecture Review (20 phút)¶
SOLID Principles trong Python¶
1. Single Responsibility Principle:
# Không tốt - class làm quá nhiều việc
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def save_to_database(self):
# Database logic
pass
def send_email(self):
# Email logic
pass
def validate_email(self):
# Validation logic
pass
# Tốt - chia thành nhiều class chuyên biệt
class User:
def __init__(self, name, email):
self.name = name
self.email = email
class UserRepository:
def save(self, user):
# Database logic
pass
class EmailService:
def send(self, user, message):
# Email logic
pass
class EmailValidator:
def validate(self, email):
# Validation logic
pass
2. Function Design Best Practices:
def calculate_order_total(items, tax_rate, discount_code=None, shipping_cost=0):
"""
Tính tổng tiền đơn hàng
Args:
items (list): Danh sách sản phẩm
tax_rate (float): Tỷ lệ thuế (0.0 - 1.0)
discount_code (str, optional): Mã giảm giá
shipping_cost (float): Phí vận chuyển
Returns:
dict: {
'subtotal': float,
'tax': float,
'discount': float,
'shipping': float,
'total': float
}
Raises:
ValueError: Khi tax_rate không hợp lệ
TypeError: Khi items không phải list
"""
if not isinstance(items, list):
raise TypeError("Items phải là list")
if not 0 <= tax_rate <= 1:
raise ValueError("Tax rate phải từ 0 đến 1")
subtotal = sum(item['price'] * item['quantity'] for item in items)
tax = subtotal * tax_rate
discount = calculate_discount(subtotal, discount_code)
total = subtotal + tax - discount + shipping_cost
return {
'subtotal': round(subtotal, 2),
'tax': round(tax, 2),
'discount': round(discount, 2),
'shipping': round(shipping_cost, 2),
'total': round(total, 2)
}
def calculate_discount(subtotal, discount_code):
"""Tính số tiền giảm giá"""
if not discount_code:
return 0
discount_rules = {
'SAVE10': 0.1,
'SAVE20': 0.2,
'NEWUSER': 0.15,
}
rate = discount_rules.get(discount_code.upper(), 0)
return subtotal * rate
Error Handling Strategy¶
class AppError(Exception):
"""Base exception cho ứng dụng"""
pass
class ValidationError(AppError):
"""Lỗi validation dữ liệu"""
pass
class DatabaseError(AppError):
"""Lỗi database"""
pass
class NetworkError(AppError):
"""Lỗi network"""
pass
def safe_execute(func, *args, **kwargs):
"""
Decorator/wrapper để execute function safely
"""
try:
return func(*args, **kwargs)
except ValidationError as e:
print(f"❌ Lỗi dữ liệu: {e}")
return None
except DatabaseError as e:
print(f"❌ Lỗi database: {e}")
return None
except NetworkError as e:
print(f"❌ Lỗi mạng: {e}")
return None
except Exception as e:
print(f"❌ Lỗi không xác định: {e}")
return None
# Usage
result = safe_execute(risky_function, param1, param2=value)
if result is not None:
print("Success!")
IV. Advanced Functions (30 phút)¶
Bài 1: Function Decorators (10 phút)¶
Đề bài: Tạo các decorators để mở rộng chức năng của functions.
Phân tích đề
Decorators cần tạo:
- Timer Decorator: Đo thời gian thực thi function
- Retry Decorator: Tự động thử lại khi function fail
- Validation Decorator: Kiểm tra kiểu dữ liệu input
- Logging Decorator: Ghi log các lần gọi function
Pattern Decorator:
def decorator_name(func):
def wrapper(*args, **kwargs):
# Code trước khi gọi function
result = func(*args, **kwargs)
# Code sau khi gọi function
return result
return wrapper
Ứng dụng thực tế: - Timer: Performance monitoring - Retry: Network calls, database operations - Validation: API endpoints, user input
Gợi ý code
import time
import functools
def timer(func):
"""Decorator đo thời gian thực thi"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"⏱️ {func.__name__} took {end_time - start_time:.4f} seconds")
return result
return wrapper
def retry(max_attempts=3, delay=1):
"""Decorator retry khi function fail"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts - 1:
raise e
print(f"Attempt {attempt + 1} failed: {e}")
time.sleep(delay)
return None
return wrapper
return decorator
def validate_types(**expected_types):
"""Decorator validate kiểu dữ liệu input"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Validate kwargs
for param_name, expected_type in expected_types.items():
if param_name in kwargs:
value = kwargs[param_name]
if not isinstance(value, expected_type):
raise TypeError(
f"Parameter '{param_name}' must be {expected_type.__name__}, "
f"got {type(value).__name__}"
)
return func(*args, **kwargs)
return wrapper
return decorator
# Example usage
@timer
@retry(max_attempts=3, delay=0.5)
@validate_types(name=str, age=int, score=float)
def process_student_data(name, age, score):
"""Process student data with validation and retry"""
if age < 0:
raise ValueError("Age cannot be negative")
if not 0 <= score <= 10:
raise ValueError("Score must be between 0 and 10")
# Simulate processing
time.sleep(0.1)
return {
'name': name.title(),
'age': age,
'score': round(score, 2),
'grade': 'A' if score >= 8 else 'B' if score >= 6 else 'C'
}
# Test
try:
result = process_student_data(name="john doe", age=20, score=8.7)
print(f"Result: {result}")
except Exception as e:
print(f"Error: {e}")
Bài 2: Functional Programming (10 phút)¶
Đề bài: Áp dụng functional programming để xử lý dữ liệu.
Phân tích đề
Functional Programming Concepts:
Function | Mục đích | Ví dụ |
---|---|---|
map() | Transform dữ liệu | Tính điểm trung bình cho từng học sinh |
filter() | Lọc dữ liệu | Chọn học sinh giỏi (avg >= 8.0) |
reduce() | Tổng hợp dữ liệu | Tính tổng điểm của tất cả học sinh |
lambda | Function ngắn gọn | lambda x: x['average'] >= 8.0 |
Workflow xử lý dữ liệu:
1. Raw data → Transform (map)
2. Transformed data → Filter (filter)
3. Filtered data → Aggregate (reduce)
Gợi ý code
from functools import reduce
import operator
def functional_data_processing():
"""Demo functional programming concepts"""
# Sample data
students = [
{'name': 'An', 'age': 20, 'scores': [8, 9, 7, 8.5]},
{'name': 'Bình', 'age': 19, 'scores': [7, 8, 6, 7.5]},
{'name': 'Cường', 'age': 21, 'scores': [9, 9.5, 8.5, 9]},
{'name': 'Dung', 'age': 18, 'scores': [6, 7, 5, 6.5]},
{'name': 'Em', 'age': 20, 'scores': [8.5, 9, 8, 8.5]},
]
# 1. Map - Transform data
students_with_avg = list(map(
lambda s: {
**s,
'average': round(sum(s['scores']) / len(s['scores']), 2)
},
students
))
# 2. Filter - Select data
excellent_students = list(filter(
lambda s: s['average'] >= 8.0,
students_with_avg
))
# 3. Reduce - Aggregate data
total_average = reduce(
lambda acc, s: acc + s['average'],
students_with_avg,
0
) / len(students_with_avg)
# 4. Sort with custom key
sorted_students = sorted(
students_with_avg,
key=lambda s: (-s['average'], s['age']) # Desc by avg, asc by age
)
# Display results
print("FUNCTIONAL DATA PROCESSING DEMO")
print("="*60)
print("\n1. Students with averages:")
for student in students_with_avg:
print(f" {student['name']}: {student['average']}")
print(f"\n2. Excellent students (avg >= 8.0): {len(excellent_students)}")
for student in excellent_students:
print(f" {student['name']}: {student['average']}")
print(f"\n3. Class average: {total_average:.2f}")
print("\n4. Sorted by average (desc) then age (asc):")
for student in sorted_students:
print(f" {student['name']} (age {student['age']}): {student['average']}")
if __name__ == "__main__":
functional_data_processing()
4. Sort with custom key¶
sorted_students = sorted( students_with_avg, key=lambda s: (-s['average'], s['age']) # Desc by avg, asc by age )
5. Group by age¶
from itertools import groupby grouped_by_age = {} for age, group in groupby( sorted(students_with_avg, key=lambda s: s['age']), key=lambda s: s['age'] ): grouped_by_age[age] = list(group)
Display results¶
print("="60) print("FUNCTIONAL DATA PROCESSING DEMO") print("="60)
print("\n1. Students with averages:") for student in students_with_avg: print(f" {student['name']}: {student['average']}")
print(f"\n2. Excellent students (avg >= 8.0): {len(excellent_students)}") for student in excellent_students: print(f" {student['name']}: {student['average']}")
print(f"\n3. Class average: {total_average:.2f}")
print("\n4. Sorted by average (desc) then age (asc):") for student in sorted_students: print(f" {student['name']} (age {student['age']}): {student['average']}")
print("\n5. Grouped by age:") for age, students_list in grouped_by_age.items(): names = [s['name'] for s in students_list] print(f" Age {age}: {', '.join(names)}")
Advanced lambda examples¶
def lambda_examples(): """Advanced lambda function examples"""
# 1. Lambda with multiple parameters
calculate_bmi = lambda weight, height: round(weight / (height ** 2), 2)
# 2. Lambda for sorting complex data
products = [
{'name': 'Laptop', 'price': 1000, 'rating': 4.5, 'stock': 10},
{'name': 'Mouse', 'price': 25, 'rating': 4.2, 'stock': 50},
{'name': 'Keyboard', 'price': 75, 'rating': 4.7, 'stock': 30},
]
# Sort by rating desc, then by price asc
sorted_products = sorted(
products,
key=lambda p: (-p['rating'], p['price'])
)
# 3. Lambda for conditional operations
grade_calculator = lambda score: (
'A' if score >= 90 else
'B' if score >= 80 else
'C' if score >= 70 else
'D' if score >= 60 else
'F'
)
# 4. Lambda with filter for complex conditions
available_expensive_products = list(filter(
lambda p: p['price'] > 50 and p['stock'] > 0 and p['rating'] >= 4.0,
products
))
print("\nLAMBDA EXAMPLES:")
print(f"BMI calculation: {calculate_bmi(70, 1.75)}")
print(f"Grade for 85: {grade_calculator(85)}")
print(f"Available expensive products: {len(available_expensive_products)}")
if name == "main": functional_data_processing() lambda_examples()
### Bài 3: Advanced Module System (10 phút)
**Tạo package structure:**
my_project/ ├── main.py ├── config.py ├── utils/ │ ├── init.py │ ├── file_operations.py │ ├── data_processing.py │ └── validators.py ├── models/ │ ├── init.py │ ├── user.py │ └── product.py └── services/ ├── init.py ├── database.py └── email_service.py
**config.py:**
```python
import os
from pathlib import Path
class Config:
"""Application configuration"""
# Base paths
BASE_DIR = Path(__file__).parent
DATA_DIR = BASE_DIR / 'data'
LOGS_DIR = BASE_DIR / 'logs'
# Database
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///app.db')
# Email
EMAIL_HOST = os.getenv('EMAIL_HOST', 'smtp.gmail.com')
EMAIL_PORT = int(os.getenv('EMAIL_PORT', '587'))
# Application
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
VERSION = '1.0.0'
@classmethod
def create_directories(cls):
"""Create necessary directories"""
cls.DATA_DIR.mkdir(exist_ok=True)
cls.LOGS_DIR.mkdir(exist_ok=True)
utils/init.py:
"""
Utilities package for common functions
"""
from .file_operations import FileManager
from .data_processing import DataProcessor
from .validators import Validator
__all__ = ['FileManager', 'DataProcessor', 'Validator']
utils/file_operations.py:
import json
import csv
import pickle
from pathlib import Path
from typing import Any, Dict, List
class FileManager:
"""Handle file operations with different formats"""
@staticmethod
def read_json(file_path: str) -> Dict[str, Any]:
"""Read JSON file"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
raise FileNotFoundError(f"File not found: {file_path}")
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON format: {e}")
@staticmethod
def write_json(data: Dict[str, Any], file_path: str, indent: int = 2) -> None:
"""Write data to JSON file"""
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=indent, ensure_ascii=False)
@staticmethod
def read_csv(file_path: str) -> List[Dict[str, str]]:
"""Read CSV file as list of dictionaries"""
with open(file_path, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
return list(reader)
@staticmethod
def write_csv(data: List[Dict[str, Any]], file_path: str) -> None:
"""Write data to CSV file"""
if not data:
return
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
@staticmethod
def save_pickle(obj: Any, file_path: str) -> None:
"""Save object using pickle"""
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'wb') as f:
pickle.dump(obj, f)
@staticmethod
def load_pickle(file_path: str) -> Any:
"""Load object from pickle file"""
with open(file_path, 'rb') as f:
return pickle.load(f)
main.py - Demo application:
#!/usr/bin/env python3
"""
Main application demonstrating advanced module usage
"""
import logging
from config import Config
from utils import FileManager, DataProcessor, Validator
from models import User, Product
def setup_logging():
"""Setup application logging"""
Config.create_directories()
logging.basicConfig(
level=logging.DEBUG if Config.DEBUG else logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(Config.LOGS_DIR / 'app.log'),
logging.StreamHandler()
]
)
def demo_application():
"""Demo the complete application"""
logger = logging.getLogger(__name__)
logger.info(f"Starting application v{Config.VERSION}")
try:
# Create sample data
users = [
User("U001", "Nguyễn Văn An", "an@email.com", 25),
User("U002", "Trần Thị Bình", "binh@email.com", 30),
User("U003", "Lê Văn Cường", "cuong@email.com", 28),
]
products = [
Product("P001", "Laptop", 1500.00, 10),
Product("P002", "Mouse", 25.00, 50),
Product("P003", "Keyboard", 75.00, 30),
]
# Save data to files
users_data = [user.to_dict() for user in users]
products_data = [product.to_dict() for product in products]
FileManager.write_json(users_data, Config.DATA_DIR / 'users.json')
FileManager.write_csv(products_data, Config.DATA_DIR / 'products.csv')
logger.info("Data saved successfully")
# Process data
processor = DataProcessor()
# Load and validate
loaded_users = FileManager.read_json(Config.DATA_DIR / 'users.json')
loaded_products = FileManager.read_csv(Config.DATA_DIR / 'products.csv')
print("="*60)
print("APPLICATION DEMO")
print("="*60)
print(f"Loaded {len(loaded_users)} users and {len(loaded_products)} products")
# Statistics
total_inventory_value = sum(
float(p['price']) * int(p['stock'])
for p in loaded_products
)
avg_age = sum(u['age'] for u in loaded_users) / len(loaded_users)
print(f"Total inventory value: ${total_inventory_value:,.2f}")
print(f"Average user age: {avg_age:.1f}")
logger.info("Application completed successfully")
except Exception as e:
logger.error(f"Application error: {e}")
raise
if __name__ == "__main__":
setup_logging()
demo_application()
V. Project Development: Task Management System (30 phút)¶
Đề bài: Tạo một mini framework cho quản lý tasks với các tính năng:
- Task creation, modification, deletion
- Priority and status management
- File-based persistence
- Search and filtering
- Statistics and reporting
# File: task_manager/core.py
from datetime import datetime, timedelta
from enum import Enum
from typing import List, Dict, Optional
import uuid
class Priority(Enum):
LOW = 1
MEDIUM = 2
HIGH = 3
CRITICAL = 4
class Status(Enum):
TODO = "todo"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
CANCELLED = "cancelled"
class Task:
"""Task model with all necessary attributes"""
def __init__(self, title: str, description: str = "",
priority: Priority = Priority.MEDIUM,
due_date: Optional[datetime] = None):
self.id = str(uuid.uuid4())
self.title = title
self.description = description
self.priority = priority
self.status = Status.TODO
self.due_date = due_date
self.created_at = datetime.now()
self.updated_at = datetime.now()
self.completed_at = None
def update(self, **kwargs):
"""Update task attributes"""
for key, value in kwargs.items():
if hasattr(self, key):
setattr(self, key, value)
self.updated_at = datetime.now()
def complete(self):
"""Mark task as completed"""
self.status = Status.COMPLETED
self.completed_at = datetime.now()
self.updated_at = datetime.now()
def is_overdue(self) -> bool:
"""Check if task is overdue"""
if not self.due_date or self.status == Status.COMPLETED:
return False
return datetime.now() > self.due_date
def to_dict(self) -> Dict:
"""Convert task to dictionary"""
return {
'id': self.id,
'title': self.title,
'description': self.description,
'priority': self.priority.value,
'status': self.status.value,
'due_date': self.due_date.isoformat() if self.due_date else None,
'created_at': self.created_at.isoformat(),
'updated_at': self.updated_at.isoformat(),
'completed_at': self.completed_at.isoformat() if self.completed_at else None
}
@classmethod
def from_dict(cls, data: Dict) -> 'Task':
"""Create task from dictionary"""
task = cls(data['title'], data.get('description', ''))
task.id = data['id']
task.priority = Priority(data['priority'])
task.status = Status(data['status'])
if data.get('due_date'):
task.due_date = datetime.fromisoformat(data['due_date'])
task.created_at = datetime.fromisoformat(data['created_at'])
task.updated_at = datetime.fromisoformat(data['updated_at'])
if data.get('completed_at'):
task.completed_at = datetime.fromisoformat(data['completed_at'])
return task
class TaskManager:
"""Main task management system"""
def __init__(self, storage_file: str = 'tasks.json'):
self.storage_file = storage_file
self.tasks: Dict[str, Task] = {}
self.load_tasks()
def create_task(self, title: str, **kwargs) -> Task:
"""Create a new task"""
task = Task(title, **kwargs)
self.tasks[task.id] = task
self.save_tasks()
return task
def get_task(self, task_id: str) -> Optional[Task]:
"""Get task by ID"""
return self.tasks.get(task_id)
def update_task(self, task_id: str, **kwargs) -> bool:
"""Update task"""
task = self.get_task(task_id)
if task:
task.update(**kwargs)
self.save_tasks()
return True
return False
def delete_task(self, task_id: str) -> bool:
"""Delete task"""
if task_id in self.tasks:
del self.tasks[task_id]
self.save_tasks()
return True
return False
def complete_task(self, task_id: str) -> bool:
"""Mark task as completed"""
task = self.get_task(task_id)
if task:
task.complete()
self.save_tasks()
return True
return False
def search_tasks(self, query: str) -> List[Task]:
"""Search tasks by title or description"""
query = query.lower()
results = []
for task in self.tasks.values():
if (query in task.title.lower() or
query in task.description.lower()):
results.append(task)
return results
def filter_tasks(self, status: Optional[Status] = None,
priority: Optional[Priority] = None,
overdue_only: bool = False) -> List[Task]:
"""Filter tasks by criteria"""
results = list(self.tasks.values())
if status:
results = [t for t in results if t.status == status]
if priority:
results = [t for t in results if t.priority == priority]
if overdue_only:
results = [t for t in results if t.is_overdue()]
return results
def get_statistics(self) -> Dict:
"""Get task statistics"""
total = len(self.tasks)
if total == 0:
return {}
status_counts = {}
priority_counts = {}
overdue_count = 0
for task in self.tasks.values():
# Status counts
status = task.status.value
status_counts[status] = status_counts.get(status, 0) + 1
# Priority counts
priority = task.priority.name
priority_counts[priority] = priority_counts.get(priority, 0) + 1
# Overdue count
if task.is_overdue():
overdue_count += 1
completion_rate = (status_counts.get('completed', 0) / total) * 100
return {
'total_tasks': total,
'status_breakdown': status_counts,
'priority_breakdown': priority_counts,
'overdue_tasks': overdue_count,
'completion_rate': round(completion_rate, 2)
}
def save_tasks(self):
"""Save tasks to file"""
from utils import FileManager
data = {task_id: task.to_dict() for task_id, task in self.tasks.items()}
FileManager.write_json(data, self.storage_file)
def load_tasks(self):
"""Load tasks from file"""
try:
from utils import FileManager
data = FileManager.read_json(self.storage_file)
self.tasks = {
task_id: Task.from_dict(task_data)
for task_id, task_data in data.items()
}
except FileNotFoundError:
self.tasks = {}
# Demo usage
def demo_task_manager():
"""Demo the task management system"""
tm = TaskManager('demo_tasks.json')
# Create sample tasks
task1 = tm.create_task(
"Complete Python project",
description="Finish the task management system",
priority=Priority.HIGH,
due_date=datetime.now() + timedelta(days=7)
)
task2 = tm.create_task(
"Review code",
description="Code review for team project",
priority=Priority.MEDIUM,
due_date=datetime.now() + timedelta(days=3)
)
task3 = tm.create_task(
"Write documentation",
description="Update project documentation",
priority=Priority.LOW,
due_date=datetime.now() - timedelta(days=1) # Overdue
)
# Update and complete tasks
tm.update_task(task2.id, status=Status.IN_PROGRESS)
tm.complete_task(task1.id)
# Display statistics
stats = tm.get_statistics()
print("TASK MANAGEMENT DEMO")
print("="*50)
print(f"Total tasks: {stats['total_tasks']}")
print(f"Completion rate: {stats['completion_rate']}%")
print(f"Overdue tasks: {stats['overdue_tasks']}")
print("\nStatus breakdown:")
for status, count in stats['status_breakdown'].items():
print(f" {status}: {count}")
# Search and filter
overdue_tasks = tm.filter_tasks(overdue_only=True)
print(f"\nOverdue tasks: {len(overdue_tasks)}")
for task in overdue_tasks:
print(f" - {task.title} (due: {task.due_date.strftime('%Y-%m-%d')})")
if __name__ == "__main__":
demo_task_manager()
VI. Code Review & Optimization (10 phút)¶
Performance Optimization Tips¶
1. Use appropriate data structures:
# Slow for lookups
valid_ids = ['id1', 'id2', 'id3', ...]
if user_id in valid_ids: # O(n)
pass
# Fast for lookups
valid_ids = {'id1', 'id2', 'id3', ...}
if user_id in valid_ids: # O(1)
pass
2. Use generators for large datasets:
# Memory intensive
def get_all_numbers():
return [i for i in range(1000000)]
# Memory efficient
def get_all_numbers():
return (i for i in range(1000000))
3. Use caching for expensive operations:
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_calculation(n):
# Some expensive computation
return result
VII. Bài tập về nhà¶
Bài 1: Advanced Web Scraper Framework¶
Yêu cầu:
- Design a modular web scraping framework
- Support multiple data sources
- Implement caching and rate limiting
- Error handling and retry mechanisms
- Export data to multiple formats
Bài 2: Personal Finance Manager¶
Yêu cầu:
- Income/expense tracking with categories
- Budget planning and monitoring
- Financial goal setting
- Report generation with charts
- Data encryption for security
Bài 3: Code Quality Analyzer¶
Yêu cầu:
- Analyze Python code files
- Check for code smells and anti-patterns
- Generate complexity metrics
- Suggest improvements
- Create HTML reports
VIII. Chuẩn bị cho buổi sau¶
Buổi tiếp theo sẽ học về Tkinter cơ bản - tạo ứng dụng với giao diện đồ họa. Hãy chuẩn bị:
- Ôn lại event-driven programming concepts
- Tìm hiểu về GUI design principles
- Cài đặt và test Tkinter trên máy
💡 Tip học tập: Clean code is not just about working code - it's about code that's easy to read, maintain, and extend. Always think about the next developer who will read your code!