⭐ Vision Engineer · Chặng 1Bài 3/11Bài học~60 phút

Python cơ bản: rẽ nhánh và vòng lặp

if/elif/else cho tiêu chí OK/NG, for, range, enumerate, while có giới hạn, break, continue và bài tập dừng dây chuyền.

Python cơ bản: rẽ nhánh và vòng lặp

Học xong bài này, bạn sẽ

  • Viết if/elif/else cho tiêu chí OK/NG
  • Dùng for, while, range, break, continue
  • Tránh vòng lặp vô hạn

Nên học trước: Biến, kiểu dữ liệu và toán tử

Nội dung bài viết
  1. 1. Thụt lề: cách Python nhóm lệnh
  2. 2. if, elif, else
  3. 3. Vòng lặp for
  4. 4. Vòng lặp while
  5. 5. break và continue
  6. Tóm tắt
  7. Bài tập

Một trạm kiểm tra làm hai việc lặp đi lặp lại: ra quyết định (sản phẩm này OK hay NG?) và lặp (làm thế với hàng nghìn sản phẩm). Bài này dạy hai công cụ tương ứng: câu lệnh if và vòng lặp for, while.

1. Thụt lề: cách Python nhóm lệnh

Python không dùng dấu ngoặc nhọn như C# hay C++. Các lệnh thuộc cùng một khối được thụt vào 4 dấu cách sau một dòng kết thúc bằng dấu hai chấm :. VS Code tự thụt lề khi bạn nhấn Enter sau dấu :.

2. if, elif, else

do_sang = 42   # độ sáng trung bình của ảnh, 0–255

if do_sang < 50:
    print("Ảnh quá tối: kiểm tra đèn")
elif do_sang > 200:
    print("Ảnh quá sáng: giảm thời gian phơi sáng")
else:
    print("Độ sáng bình thường")
Ảnh quá tối: kiểm tra đèn

Python kiểm tra lần lượt từ trên xuống, gặp điều kiện đúng đầu tiên thì chạy khối đó và bỏ qua phần còn lại. elif và else là tùy chọn.

Ví dụ thực tế: phân loại theo nhiều tiêu chí

duong_kinh = 12.53
co_ba_via = False
lech_tam = 0.08

if co_ba_via:
    ket_qua, ly_do = "NG", "có ba via"
elif not (12.40 <= duong_kinh <= 12.60):
    ket_qua, ly_do = "NG", f"đường kính {duong_kinh} ngoài dung sai"
elif lech_tam > 0.10:
    ket_qua, ly_do = "NG", "lệch tâm quá 0.10 mm"
else:
    ket_qua, ly_do = "OK", ""

print(ket_qua, ly_do)
OK

Kiểm tra lỗi nghiêm trọng nhất trước và ghi lại lý do NG. Khi trạm loại một sản phẩm, người vận hành luôn hỏi "vì sao", và bạn cần câu trả lời có sẵn trong log.

Biểu thức điều kiện một dòng

diem = 0.87
nhan = "NG" if diem >= 0.5 else "OK"
print(nhan)   # NG

3. Vòng lặp for

for duyệt lần lượt qua từng phần tử của một dãy:

ket_qua_ca = ["OK", "OK", "NG", "OK", "NG", "OK"]

so_ng = 0
for kq in ket_qua_ca:
    if kq == "NG":
        so_ng += 1          # viết gọn của so_ng = so_ng + 1

print(f"{so_ng}/{len(ket_qua_ca)} sản phẩm NG")
2/6 sản phẩm NG

range(): lặp theo số

for i in range(3):            # 0, 1, 2
    print("Chụp ảnh lần", i)

for x in range(0, 640, 160):  # bắt đầu 0, dừng trước 640, bước 160
    print("Vạch chia tại cột", x)
Chụp ảnh lần 0
Chụp ảnh lần 1
Chụp ảnh lần 2
Vạch chia tại cột 0
Vạch chia tại cột 160
Vạch chia tại cột 320
Vạch chia tại cột 480

range(a, b) không bao gồm b. Đây là quy ước chung của Python (và của cắt ảnh bằng NumPy ở các bài sau), nên hãy làm quen ngay từ đầu.

enumerate(): vừa lấy số thứ tự vừa lấy phần tử

for stt, kq in enumerate(ket_qua_ca, start=1):
    if kq == "NG":
        print(f"Sản phẩm thứ {stt} bị NG")
Sản phẩm thứ 3 bị NG
Sản phẩm thứ 5 bị NG

Vòng lặp lồng nhau: duyệt lưới ô

Ảnh thường được chia thành lưới ô để kiểm tra từng vùng. Hai vòng lặp lồng nhau duyệt qua mọi ô:

rong, cao, o = 640, 480, 160
for y in range(0, cao, o):
    for x in range(0, rong, o):
        print(f"({x},{y})", end=" ")
    print()   # xuống dòng sau mỗi hàng
(0,0) (160,0) (320,0) (480,0)
(0,160) (160,160) (320,160) (480,160)
(0,320) (160,320) (320,320) (480,320)

4. Vòng lặp while

while lặp chừng nào điều kiện còn đúng. Dùng khi không biết trước số lần lặp, ví dụ thử lại kết nối camera:

so_lan_thu = 0
ket_noi_duoc = False

while not ket_noi_duoc and so_lan_thu < 5:
    so_lan_thu += 1
    print("Thử kết nối camera lần", so_lan_thu)
    ket_noi_duoc = so_lan_thu == 3     # giả lập: lần 3 thì kết nối được

print("Kết nối:", ket_noi_duoc)
Thử kết nối camera lần 1
Thử kết nối camera lần 2
Thử kết nối camera lần 3
Kết nối: True
Vòng lặp vô hạnNếu điều kiện không bao giờ sai, chương trình chạy mãi. Luôn có giới hạn số lần (như so_lan_thu < 5) hoặc lệnh break. Nếu lỡ chạy vô hạn, nhấn Ctrl+C trong terminal để dừng.

5. break và continue

  • break: thoát hẳn khỏi vòng lặp.
  • continue: bỏ qua phần còn lại của lượt hiện tại, sang lượt tiếp theo.
ten_files = ["a.png", "ghi_chu.txt", "b.png", "LOI.png", "c.png"]

for ten in ten_files:
    if not ten.endswith(".png"):
        continue                    # bỏ qua file không phải ảnh
    if ten.startswith("LOI"):
        print("Gặp ảnh lỗi, dừng xử lý:", ten)
        break
    print("Xử lý", ten)
Xử lý a.png
Xử lý b.png
Gặp ảnh lỗi, dừng xử lý: LOI.png

Vòng lặp chính của mọi chương trình camera bạn viết sau này có dạng while True: và thoát bằng break khi người dùng nhấn phím q. Bạn sẽ gặp lại ở chặng OpenCV.

Tóm tắt

  • Khối lệnh = dòng kết thúc bằng : + thụt lề 4 dấu cách.
  • if/elif/else kiểm tra từ trên xuống, dừng ở điều kiện đúng đầu tiên. Ghi lại lý do NG.
  • for duyệt dãy; range(a, b, buoc) không gồm b; enumerate cho số thứ tự.
  • while cần giới hạn để không chạy vô hạn; break thoát, continue bỏ qua.

Bài tập

Bài 1. Phân loại độ sáng

Cho danh sách độ sáng của 8 ảnh: [12, 130, 245, 88, 47, 201, 150, 30]. In mỗi ảnh là "tối" (<50), "sáng" (>200) hay "tốt", và đếm số ảnh tốt.

Xem đáp án
do_sang_anh = [12, 130, 245, 88, 47, 201, 150, 30]
so_tot = 0
for i, v in enumerate(do_sang_anh, start=1):
    if v < 50:
        loai = "tối"
    elif v > 200:
        loai = "sáng"
    else:
        loai = "tốt"
        so_tot += 1
    print(f"Ảnh {i}: {v} → {loai}")
print("Số ảnh tốt:", so_tot)
Ảnh 1: 12 → tối
Ảnh 2: 130 → tốt
Ảnh 3: 245 → sáng
Ảnh 4: 88 → tốt
Ảnh 5: 47 → tối
Ảnh 6: 201 → sáng
Ảnh 7: 150 → tốt
Ảnh 8: 30 → tối
Số ảnh tốt: 3

Bài 2. Ba NG liên tiếp

Dây chuyền phải dừng nếu có 3 sản phẩm NG liên tiếp (dấu hiệu máy hỏng). Với ["OK","NG","NG","OK","NG","NG","NG","OK"], in vị trí (bắt đầu từ 1) của sản phẩm thứ ba trong chuỗi NG đó rồi dừng vòng lặp.

Xem đáp án
ds = ["OK", "NG", "NG", "OK", "NG", "NG", "NG", "OK"]
lien_tiep = 0
for stt, kq in enumerate(ds, start=1):
    if kq == "NG":
        lien_tiep += 1
    else:
        lien_tiep = 0           # gặp OK thì đếm lại từ đầu
    if lien_tiep == 3:
        print("DỪNG DÂY CHUYỀN tại sản phẩm", stt)
        break
DỪNG DÂY CHUYỀN tại sản phẩm 7

Bài 3. Bảng thời gian phơi sáng

In bảng thời gian phơi sáng từ 100 µs đến 1000 µs, bước 100 µs, kèm độ nhòe (pixel) khi vật chạy 0,5 m/s và mỗi pixel là 0,05 mm. Gợi ý: quãng đường vật đi = vận tốc × thời gian; đổi đơn vị cẩn thận.

Xem đáp án
van_toc_mm_s = 0.5 * 1000      # 0,5 m/s = 500 mm/s
mm_moi_px = 0.05
for t_us in range(100, 1001, 100):
    quang_duong_mm = van_toc_mm_s * t_us / 1_000_000
    nhoe_px = quang_duong_mm / mm_moi_px
    canh_bao = "  ← nhòe quá 1 pixel" if nhoe_px > 1 else ""
    print(f"{t_us:5d} µs: nhòe {nhoe_px:.1f} px{canh_bao}")
  100 µs: nhòe 1.0 px
  200 µs: nhòe 2.0 px  ← nhòe quá 1 pixel
  300 µs: nhòe 3.0 px  ← nhòe quá 1 pixel
  400 µs: nhòe 4.0 px  ← nhòe quá 1 pixel
  500 µs: nhòe 5.0 px  ← nhòe quá 1 pixel
  600 µs: nhòe 6.0 px  ← nhòe quá 1 pixel
  700 µs: nhòe 7.0 px  ← nhòe quá 1 pixel
  800 µs: nhòe 8.0 px  ← nhòe quá 1 pixel
  900 µs: nhòe 9.0 px  ← nhòe quá 1 pixel
 1000 µs: nhòe 10.0 px  ← nhòe quá 1 pixel

Kết luận: muốn ảnh không nhòe quá 1 pixel ở tốc độ này, thời gian phơi sáng phải ≤ 100 µs. Đó là lý do phải dùng đèn strobe ở chặng 5.

Bài tiếp theo
Ban biên tập HọcFree

Chúng tôi viết những bài hướng dẫn dễ hiểu, thực tế để ai cũng có thể tự học lập trình và ngoại ngữ, hoàn toàn miễn phí.