
1. Giới thiệu chung
Trong tuần này chúng ta ôn tập hai chủ đề quan trọng: lập trình hướng đối tượng (OOP) trong Python và cách xây dựng ứng dụng tương tác đơn giản để triển khai mô hình ML bằng Streamlit/Gradio.
- OOP giúp tổ chức mã nguồn sạch hơn, dễ tái sử dụng và mở rộng. Thay vì viết các hàm rời rạc và thao tác trực tiếp với dữ liệu (cách lập trình thủ tục), OOP tạo ra các lớp (class) mô tả thuộc tính và hành vi chung, sau đó khởi tạo các đối tượng cụ thể. Mọi thao tác sẽ gắn liền với đối tượng, hạn chế lỗi và giảm lặp mã.
- Sau khi xây dựng mô hình ML, chúng ta cần cách đưa mô hình tới người dùng. Trước đây phải viết front‑end/back‑end bằng HTML/JS/Python – tương đối phức tạp. Thư viện như Gradio cho phép tạo web demo chỉ bằng Python; nó cung cấp các component nhập/xuất dữ liệu sẵn có để kết nối tới hàm dự đoán. Vì vậy, việc triển khai trở nên nhẹ nhàng hơn, phù hợp cho nhóm không chuyên lập trình web.
2. Lập trình hướng đối tượng (OOP) trong Python
2.1. Motivation của OOP
Lập trình thủ tục xử lý dữ liệu bằng các biến và hàm rời rạc. Khi chương trình phức tạp hơn (quản lý nhân sự, hệ thống lớn), việc lặp lại cấu trúc dữ liệu và hàm dẫn tới mã dài dòng, khó bảo trì. OOP giải quyết bằng cách:
- Đóng gói dữ liệu và các hàm liên quan vào một lớp, giúp hạn chế truy cập tuỳ tiện.
-
Khả năng kế thừa và tái sử dụng: lớp con có thể kế thừa thuộc tính/phương thức từ lớp cha và mở rộng thêm.
-
Đa hình: cùng một phương thức có thể có nhiều cách triển khai tùy thuộc vào lớp con.
-
Code gọn gàng hơn, dễ bảo trì và mở rộng.
2.2. Ý tưởng cốt lõi
1. Lớp (Class): Khuôn mẫu do người dùng định nghĩa, chứa thuộc tính và phương thức chung của một nhóm đối tượng. Ví dụ, lớp Dog mô tả các loài chó với thuộc tính name, kind, và hành vi bark().
2. Đối tượng (Object): Một thể hiện cụ thể của lớp với giá trị thuộc tính riêng. Khi gọi dog1 = Dog("Bella", "Pug"), dog1 có tên Bella và giống Pug nhưng vẫn sử dụng chung các phương thức của lớp.
3. Hàm khởi tạo init: Hàm đặc biệt được gọi khi tạo đối tượng để khởi tạo giá trị thuộc tính. Tham số đầu tiên self đại diện cho chính đối tượng.
4. Phương thức (method): Hàm định nghĩa bên trong lớp và nhận self như đối số đầu tiên. Chúng mô tả hành vi của đối tượng (ví dụ bark(), eat()).
5. Thuộc tính lớp vs thuộc tính cá thể: Biến khai báo trực tiếp trong lớp là thuộc tính lớp, dùng chung cho mọi đối tượng. Biến gán cho self trong init là thuộc tính cá thể, riêng cho từng đối tượng.
6. Đóng gói & access modifiers:
- Public :tên bình thường, truy cập từ mọi nơi.
- Protected: bắt đầu bằng "_" nên chỉ sử dụng trong nội bộ lớp và lớp con.
- Private: bắt đầu bằng "__" không thể truy cập trực tiếp từ ngoài lớp; ta cần getter/setter để đọc/ghi an toàn.

Hình 1: Lớp là khuôn mẫu chung; từ đó ta tạo nhiều đối tượng với giá trị thuộc tính riêng nhưng dùng chung phương thức.
2.3. Cú pháp và ví dụ
Khai báo lớp Dog và tạo đối tượng:
class Dog:
def __init__(self, name, kind): # hàm khởi tạo
self.name = name
self.kind = kind
def bark(self):
print(f"{self.name} kêu: gâu gâu")
def eat(self):
print(f"{self.name} đang ăn")
# Khởi tạo hai đối tượng
puppy = Dog("Bella", "Pug")
puppy.bark() # in: Bella kêu: gâu gâu
big_dog = Dog("Buddy", "Chihuahua")
big_dog.eat() # in: Buddy đang ăn
Định nghĩa getter/setter để đóng gói dữ liệu:
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # private
def get_salary(self):
return self.__salary
def set_salary(self, new_amount):
if new_amount > 0:
self.__salary = new_amount
else:
print("Salary must be positive!")
emp = Employee("Alice", 50000)
print(emp.get_salary()) # 50000
emp.set_salary(-1000) # thông báo lỗi
2.4. Lỗi sai thường gặp
| Lỗi phổ biến | Mô tả & cách khắc phục |
|---|---|
| Quên tham số self | Khi định nghĩa phương thức mà thiếu self, Python sẽ tự truyền đối tượng vào làm tham số đầu tiên khiến số lượng tham số không khớp, dẫn tới lỗi. Luôn đặt self đầu tiên cho các instance method. |
| Quên khởi tạo init ở Class | Ghi nhớ và bổ sung thêm nếu không sẽ bị lỗi |
| Nhầm lẫn giữa thuộc tính lớp và thuộc tính instance | Khai báo biến trực tiếp trong lớp sẽ trở thành thuộc tính dùng chung cho tất cả đối tượng. Nếu muốn mỗi đối tượng có giá trị riêng, hãy gán qua self trong init. |
| Truy cập biến private trực tiếp | Các biến bắt đầu bằng __ bị đổi tên nội bộ (name mangling) và không nên truy cập trực tiếp. Hãy sử dụng getter/setter để đọc và ghi giá trị. |
| Truy cập biến Protected | Mục đích khi lập trình viên khởi tạo _ cho biến thì khả năng cao ý của họ là biến này quan trọng đừng động vào tùy tiện |
3. Phát triển ứng dụng tương tác bằng Streamlit & Gradio
3.1. Motivation
Sau khi huấn luyện xong mô hình ML, ta cần cách để người dùng tương tác với model. Triển khai hoàn chỉnh thường đòi hỏi xây dựng back‑end và front‑end. Thư viện Gradio ra đời giúp tạo giao diện web trực quan chỉ với vài dòng code Python. Streamlit cũng theo triết lý tương tự: hỗ trợ dựng nhanh các data apps mà không cần biết HTML/JS.

Hình 2: Vòng đời ML – sau bước huấn luyện mô hình cần xây dựng một giao diện (web app) để nhận input và trả về kết quả dự đoán.
3.2. Streamlit làm được những gì?
Làm Dashboard, báo cáo dữ liệu, vẽ biểu đồ đẹp.
- Cơ chế hoạt động:
- Mỗi khi bạn bấm một nút bất kỳ trên web, Streamlit sẽ đọc lại toàn bộ mã nguồn từ dòng đầu tiên đến dòng cuối cùng.
- Vấn đề: Vì nó đọc lại từ đầu, nó sẽ "quên" mất bạn vừa làm gì trước đó (ví dụ: vừa bấm nút "Thêm việc" thì danh sách công việc bị reset về rỗng).
- Giải pháp (Session State): Hãy coi session_state giống như một cái két sắt. Dù trang web có chạy lại (rerun), những gì bạn cất trong két sắt (biến st.session_state) sẽ vẫn còn nguyên.
=> Tóm lại về Streamlit: Dùng khi bạn muốn làm một trang web có nhiều biểu đồ, dữ liệu hiển thị phức tạp. Nhớ dùng "két sắt" session_state để lưu dữ liệu.

Hình 3: Mô tả minh họa làm biểu đồ bằng streamlit
3.3. Gradio làm được những gì?
Nó thường được sử dụng để Demo nhanh mô hình AI (Nhập ảnh -> Ra tên con vật; Nhập câu hỏi -> Ra câu trả lời).
Cơ chế hoạt động:
1. Bạn viết một hàm xử lý (Ví dụ: def xuly(anh): return "Con meo").
2. Bạn bảo Gradio: "Đầu vào là cái Ảnh, Đầu ra là Chữ".
3. Gradio tự vẽ ra cái ô để up ảnh và cái ô hiện chữ. Xong! .
Điểm hay: Nó không chạy lại toàn bộ code như Streamlit, nó chỉ chạy đúng cái hàm xử lý khi bạn bấm nút.
=> Tóm lại về Gradio: Dùng khi bạn muốn demo nhanh: "Input vào là gì -> Model xử lý -> Output ra là gì".

Hình 4: Mô tả Workflow của Gradio Input - Process - Out
3.4. Triển khai Deploy
3.4.1. Deploy Gradio lên Hugging Face Spaces
Hugging Face Spaces là nền tảng giúp chạy demo AI miễn phí. Quy trình triển khai như sau:
1. Đăng nhập vào https://huggingface.co/spaces và chọn +New Space.
2. Điền tên và chọn SDK là Gradio; có thể chọn phần cứng nếu ứng dụng nặng.
3. Tải lên file app.py (mã ứng dụng) và requirements.txt thông qua mục Upload files.
4. Nhấn Commit changes; hệ thống sẽ tự build và chạy ứng dụng. Sau khi hoàn tất, trang app sẽ hiển thị đường dẫn truy cập công khai.
3.4.2. Deploy Streamlit lên Streamlit Cloud
- Đưa code Streamlit và requirements.txt lên một repository GitHub.
- Đăng nhập vào https://streamlit.io/cloud bằng tài khoản GitHub; chọn “New App” và trỏ tới repository của bạn.
- Click Deploy. Streamlit Cloud sẽ cài đặt các thư viện và chạy app.
Lưu ý: Cả hai nền tảng đều có giới hạn tài nguyên. Nếu app cần GPU hoặc nhiều tài nguyên, bạn cần nâng cấp hoặc tự triển khai trên server riêng.
4. Tổng hợp kiến thức
4.1. OOP trong Python
| Mục | Mô tả & Cú pháp |
|---|---|
| Class | class ClassName: dùng để định nghĩa lớp. Thuộc tính lớp khai báo trực tiếp trong lớp; thuộc tính cá thể gán trong init. |
| Tạo đối tượng | obj = ClassName(args) sẽ gọi init. Dùng obj.attribute để truy cập thuộc tính. |
| Method | Định nghĩa hàm bên trong lớp với tham số đầu tiên là self. |
| Encapsulation | Ẩn thông tin bằng cách dùng _attribute (protected) hoặc __attribute (private). Tạo phương thức getter/setter để truy cập an toàn. |
| Kế thừa | class Child(Parent): kế thừa thuộc tính/phương thức từ Parent. Có thể override phương thức. |
| Đa hình | Các lớp con có thể triển khai cùng một phương thức theo cách khác nhau; Python chọn phương thức phù hợp khi gọi. |
4.2. Streamlit và Gradio
| Tiêu chí | Streamlit | Gradio |
|---|---|---|
| Triết lý | Biến script Python thành app; tập trung vào data dashboard & demo nhanh. | Tạo UI tương tác cho mô hình ML với minimal code. |
| Cơ chế rerun | Chạy lại toàn bộ script khi có tương tác; cần dùng session_state để lưu dữ liệu. | Không rerun toàn bộ; chỉ xử lý hàm khi submit; giao diện tách biệt. |
| Component nhập/xuất | Nhiều widget cho text, file, biểu đồ; dễ tạo dashboard. | Hơn 30 built‑in input/output component (Textbox, Image, Slider, CheckboxGroup, Label, JSON, Plot…). |
| Layout | Sử dụng st.columns, st.expander; không hỗ trợ tab nhiều mức. | gr.Blocks cùng Row, Column, Tabs cho layout linh hoạt. |
| Triển khai | Streamlit Cloud (miễn phí) hoặc tự host. | Hugging Face Spaces, share=True để nhận link public. |
5. Tài Liệu Tham Khảo
[1] Slide Bài Giảng AIO 2026 : Warm up - Review 08: Basic-OOP 19 - 1 - 2026 _ TA Quốc Thái
[2] Predocs AIO 2026: 19 - 1 - 2026
[3] Slide Bài Giảng AIO 2026 : Warm up - Review 09: Gradio 22 - 1 - 2026 _ TA Đăng Nhã
[4] Predocs AIO 2026: 22 - 1 - 2026
Chưa có bình luận nào. Hãy là người đầu tiên!