1. Introduction
Procedural programming
Mô tả tổng quan: Lập trình thủ tục (Procedural Programming) là phong cách lập trình truyền thống, trong đó chương trình được tổ chức thành các hàm (function/procedure) thao tác trực tiếp trên dữ liệu. Cách tiếp cận này thường tuân theo hướng top–down (từ trên xuống), chia nhỏ bài toán thành các bước tuần tự. Lập trình thủ tục được xây dựng dựa trên một số nguyên tắc:
- Top-down approach: Chia nhỏ bài toán thành các thủ tục/hàm con để xử lý.
- Security: Quản lý truy cập dữ liệu thông qua các thủ tục, tuy nhiên không có cơ chế che giấu dữ liệu mạnh mẽ như OOP.
- Maintenance: Dễ bảo trì đối với chương trình nhỏ, nhưng khi hệ thống lớn có thể phức tạp vì dữ liệu và hàm gắn kết chặt chẽ.
- Reusability: Hàm có thể tái sử dụng ở nhiều nơi khác nhau.
- Implementation: Chương trình triển khai tuần tự, theo từng bước được định nghĩa trước. Trong mô hình này, dữ liệu và hàm được mô tả riêng biệt:
- Functions (thủ tục): Chứa logic xử lý.
- Data (dữ liệu): Các biến/struct được truyền vào hàm.
- Các hàm tương tác trực tiếp với dữ liệu → dễ dẫn đến phụ thuộc.

OOP programming
Bốn nguyên tắc cốt lõi của OOP: a. Encapsulation (Đóng gói)
-
Đóng gói dữ liệu và hành vi liên quan vào trong một class.
-
Giúp ẩn chi tiết bên trong (internal state) và chỉ cung cấp phương thức (method) để tương tác.
-
Tăng tính bảo mật, tránh can thiệp trực tiếp vào dữ liệu. b. Abstraction (Trừu tượng hóa)
-
Chỉ tập trung vào cái cần thiết, che giấu chi tiết cài đặt.
-
Định nghĩa interface hoặc abstract class để mô tả hành vi chung.
Ví dụ:
Class → Định nghĩa chung, là cái trừu tượng. Ví dụ: Cái bàn
Object → Là đối tượng thật trong hệ thống. Ví dụ: Cái bàn hiện tại đang để cái laptop
c. Inheritance (Kế thừa)
- Cho phép một class kế thừa thuộc tính và phương thức từ class khác.
- Giúp tái sử dụng code, mở rộng hệ thống dễ dàng. d. Polymorphism (Đa hình)
- Cho phép cùng một interface có nhiều cách triển khai khác nhau.
- Một phương thức có thể hành xử khác nhau tùy đối tượng cụ thể.
Important
- Interface là một hợp đồng (contract) mô tả những gì một lớp phải làm, nhưng không nói làm như thế nào.
- Interface chỉ chứa khai báo phương thức (method signatures) và hằng số, không có phần cài đặt logic (trừ một số ngôn ngữ hiện đại cho phép default methods).
- Một class khi implement (cài đặt) interface phải triển khai đầy đủ tất cả phương thức được khai báo trong interface.
Class Diagram
Trong lập trình hướng đối tượng (OOP), cấu trúc của hệ thống được mô tả bằng class diagram – biểu đồ lớp. Một lớp (class) mô tả tập hợp các thuộc tính (attributes) và phương thức (methods) của đối tượng, đồng thời xác định mối quan hệ giữa các đối tượng với nhau. Các thành phần chính
- Classes: đại diện cho đối tượng trong thế giới thực.
- Attributes (thuộc tính): đặc điểm mô tả đối tượng (tên, màu sắc, tuổi…).
- Methods (operations): hành vi mà đối tượng có thể thực hiện (ăn, ngủ, đi…).
- Relationships among objects: quan hệ giữa các class (association, inheritance…).
- Access modifiers:
+public: có thể truy cập từ bên ngoài.-private: chỉ dùng trong nội bộ class.#protected~package
Relationships
Association (Kết hợp)
- Mối quan hệ “có liên kết” giữa các lớp.
- Ví dụ:
Studentenrolls inCourse. - Có thể phân loại:
- One-to-One (1–1)
- One-to-Many (1–N)
- Many-to-Many (M–N) Trong UML: vẽ bằng một đường thẳng nối 2 lớp.
Aggregation (Kết tập)
- Là một dạng Association đặc biệt, mô tả quan hệ “có chứa” nhưng các đối tượng vẫn độc lập.
- Ví dụ:
Teamcó nhiềuPlayer, nhưng nếu giải tánTeam, cácPlayervẫn tồn tại. - Trong UML: đường thẳng với hình thoi rỗng ở phía lớp “toàn thể”.
Composition (Thành phần)
- à một dạng Association đặc biệt: Mối quan hệ “có chứa” chặt chẽ hơn Aggregation.
- Nếu đối tượng cha bị hủy, các đối tượng con cũng bị hủy theo.
- Ví dụ:
Housecó nhiềuRoom. Nếu phá hủyHouse,Roomcũng không tồn tại. - Trong UML: đường thẳng với hình thoi đặc.
Inheritance (Generalization / Kế thừa)
- Mối quan hệ “is-a” (là một).
- Ví dụ:
Dogis aAnimal. - Trong UML: đường thẳng với mũi tên rỗng hướng lên lớp cha.
Dependency (Phụ thuộc)
- Khi một lớp sử dụng tạm thời một lớp khác (thường trong tham số hoặc nội bộ phương thức).
- Ví dụ:
OrderServiceusesEmailServiceđể gửi mail. - Trong UML: đường chấm chấm với mũi tên hướng về lớp được phụ thuộc.
2. Objects and Classes
3. Delegation
Delegation trong lập trình hướng đối tượng (OOP) là một Design Pattern trong đó một đối tượng uỷ quyền (delegate) - có thể hiểu là nhờ vả - công việc của nó cho một đối tượng khác để thực hiện thay vì tự xử lý. Nói cách khác: “thay vì kế thừa, tôi nhờ một đối tượng khác làm giúp.”
Khi nào dùng delegation?
- Khi muốn tái sử dụng hành vi mà không cần kế thừa (composition > inheritance).
- Khi muốn chia nhỏ trách nhiệm, tăng tính linh hoạt (principle of single responsibility).
- Khi không thể hoặc không nên sử dụng kế thừa do giới hạn kỹ thuật hoặc thiết kế.
class Engine:
def start(self):
print("Engine started.")
class Car:
def __init__(self):
self.engine = Engine() # delegate object
def start(self):
print("Starting car...")
self.engine.start() # delegation: car uỷ quyền việc khởi động cho engine
car = Car()
car.start()
>>
Starting car...
Engine started.So sánh với Kế thừa:
| Tiêu chí | Kế thừa (Inheritance) | Ủy quyền (Delegation) |
| Quan hệ | Cha-con | Hợp |
| Mở rộng hành vi | Dễ nhưng chặt chẽ | Linh hoạt, dễ thay đổi |
| Độ kết dính (coupling) | Cao | Thấp |
| Khả năng tái sử dụng | Thường khó tái sử dụng một phần | Dễ tái sử dụng thông qua thành phần |
| Thực hiện trong bài Ward: |
class Ward:
def __init__(self, name: str) -> None:
self.name = name
self.people = []
def add_person(self, person):
self.people.append(person)
def describe(self):
print(f"Ward Name: {self.name}")
for person in self.people:
person.describe()
class Person:
def __init__(self, name: str, yob: int, job: str, detail: str) -> None:
self._name = name
self._yob = yob
self._job = job
self._detail = detail
def describe(self):
print(f"Name: {self._name} - YoB: {self._yob} - {self._job}: {self._detail} ")→ Class Ward delegate cho Person nhiệm vụ describe từng người thay vì Class Ward sẽ làm hết. Điều này giúp code gọn và dễ phát triển mở rộng hơn
4. Inheritance
Inheritance (Kế thừa) trong lập trình hướng đối tượng (OOP) là một cơ chế cho phép một lớp (class) con kế thừa thuộc tính (attributes) và phương thức (methods) từ một lớp cha (parent class).
Khái niệm chính:
- Superclass / Parent class: lớp cơ sở.
- Subclass / Child class: lớp kế thừa, mở rộng lớp cha.
- IS-A relationship: Quan hệ giữa subclass và superclass (ví dụ:
Dogis aAnimal). Ví dụ:
# Lớp cha
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
# Lớp con kế thừa từ Animal
class Dog(Animal):
def speak(self):
return f"{self.name} barks"
dog = Dog("Rex")
print(dog.speak()) # Rex barksVí dụ trong bài Ward:
class Person:
def __init__(self, name: str, yob: int, job: str, detail: str) -> None:
self._name = name
self._yob = yob
self._job = job
self._detail = detail
def describe(self):
print(f"Name: {self._name} - YoB: {self._yob} - {self._job}: {self._detail} ")
class Student(Person):
def __init__(self, name: str, yob: int, grade: str) -> None:
super().__init__(name, yob, job="Grade", detail= grade)
def describe(self):
super().describe()
class Teacher(Person):
def __init__(self, name: str, yob: int, subject: str) -> None:
super().__init__(name, yob, job="Subject", detail= subject)
def describe(self):
super().describe()
class Doctor(Person):
def __init__(self, name: str, yob: int, specialist: str) -> None:
super().__init__(name, yob, job="Specialist", detail= specialist)
def describe(self):
super().describe()→ Cho các vai trò kế thừa Class Person. Điều này giúp code ngắn gọn, hạn chế lặp lại và thiết kế chặt chẽ hơn.
4.4. Custom Layer in Pytorch
1. PyTorch là gì?
PyTorch là một thư viện mã nguồn mở chuyên dùng cho machine learning và deep learning, được phát triển bởi Facebook AI Research (FAIR). PyTorch được ưa chuộng vì:
- Hỗ trợ tính toán tensor hiệu năng cao (tương tự NumPy nhưng có GPU support).
- Cung cấp mô hình autograd (tự động tính đạo hàm) giúp xây dựng và huấn luyện mạng neural một cách linh hoạt.
- Thiết kế dynamic computation graph (biểu đồ tính toán động) — giúp việc debug, kiểm tra mô hình dễ dàng hơn TensorFlow 1.x.
data = torch.Tensor([3, 7, -5])
print(data)
>> tensor(([3, 7, -5])2. **torch.nn.Module** là gì?
torch.nn.Module là lớp cơ sở cho tất cả các mô hình học sâu trong PyTorch. Bất kỳ mô hình nào — từ mạng đơn giản đến phức tạp — đều nên kế thừa từ lớp này.
Cách sử dụng
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.linear = nn.Linear(10, 5)
def forward(self, x):
return self.linear(x)Giải thích:
__init__: Khởi tạo các lớp con (layers), ví dụnn.Linear,nn.Conv2d,nn.ReLU, v.v.forward: Xác định cách dữ liệu sẽ truyền qua các lớp (forward propagation). Ví dụ chạy:
model = MyModel()
x = torch.randn(2, 10) # batch size = 2, input dim = 10
output = model(x)
print(output.shape) # => torch.Size([2, 5])Custom ReLU
Custom Class ReLU được kế thừa class Module từ Pytorch
import torch
import torch.nn as nn
class MyReluActivation(nn.Module):
def __init__(self) -> None:
super().__init__()
def forward(self, x):
return torch.clamp(x, min= 0)
data = torch.Tensor([1, -2, 3])
my_relu = MyReluActivation()
output = my_relu(data)
print(output)
>> tensor([1., 0., 3.])Ở đây thư viện torch cung cấp cho chúng ta hàm torch.clamp hoạt động khá giống cơ chế của hàm ReLU nên ta có thể tận dụng.
Ta có thể điều chỉnh min= của clamp để tùy thuộc vào ngữ cảnh của bài toán.
Custom Sigmoid

import torch
import torch.nn as nn
import math
class MySigmoid(nn.Module):
def __init__(self) -> None:
super().__init__()
def forward(self, x):
result = 1 / (1 + math.exp(-x))
return result
# input data
x = torch.tensor([1.0, 5.0, -4.0])
# sigmoid function
output = torch.sigmoid(x)
print(output)
>>tensor([0.7311, 0.9933, 0.0180])Quiz:

-
Đáp án:
NameError: name ‘_Cat__age’ is not defined
→ Vì
__agelà private variable

-
Đáp án:
NameError: name ‘age’ is not defined
→ Phải là
self.age

-
Tại sao sai?
Vì khởi tạo đối tượng Cat() nhưng không truyền đủ tham số
→ Nếu muốn nó có thuộc tính age mặc định là -1 thì
class Cat: def __init__(self, age = -1): \#Add defaul value self.age = age def describe(age, name): age.__age = 9 print(age.__age, name)