Bài 30

Nhận biết lỗi chương trình

Biết và phân loại được một số loại lỗi chương trình, biết được một vài lỗi ngoại lệ thường gặp.

🚀

1. Khởi động (Engagement)

Một chương trình hoàn chỉnh được mô tả như sau: Tiếp nhận các dữ liệu đầu vào, xử lí theo yêu cầu bài toán và đưa ra kết quả đúng theo yêu cầu.

💡 Câu hỏi suy ngẫm: Theo em nếu chương trình có lỗi, thì các lỗi này sẽ như thế nào và có thể ở đâu?

Trong thực tế, chương trình có thể gặp nhiều loại lỗi khác nhau ở các giai đoạn khác nhau: từ lúc viết code, lúc nhập dữ liệu, cho đến lúc xử lý và đưa ra kết quả. Hãy cùng tìm hiểu cách nhận biết và phân loại các loại lỗi này.

📖

2. Hình thành kiến thức (Knowledge)

1. Nhận biết và phân biệt một số loại lỗi chương trình

Quan sát các trường hợp chương trình gặp lỗi sau, từ đó nhận biết và phân biệt một số loại lỗi của chương trình.

Trường hợp 1: Lỗi cú pháp (Syntax Error)

Người lập trình viết sai cú pháp lệnh, chương trình lập tức dừng lại và thông báo lỗi cú pháp.

Ví dụ:

while True print("Hello")
Python Script

Kết quả:

SyntaxError: invalid syntax
Python Script

Nguyên nhân: Thiếu dấu hai chấm (:) sau while True

Trường hợp 2: Lỗi nhập dữ liệu (ValueError)

Người dùng nhập dữ liệu sai, chương trình thông báo lỗi nhập dữ liệu không đúng khuôn dạng.

Ví dụ:

n = int(input("Nhập số nguyên n: "))
Python Script

Khi người dùng nhập: Nhập số nguyên n: 1.5

Kết quả:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
n = int(input("Nhập số nguyên n: "))
ValueError: invalid literal for int() with base 10: '1.5'
Python Script

Nguyên nhân: Không thể chuyển xâu "1.5" thành số nguyên

Trường hợp 3: Lỗi chỉ số vượt quá giới hạn (IndexError)

Chương trình thông báo lỗi chỉ số vượt quá giới hạn cho phép.

Ví dụ:

A = [1, 3, 10, 0]
for i in range(5):
    print(A[i], end = " ")
Python Script

Kết quả:

1 3 10 0 Traceback (most recent call last):
File "C:\Python\Array_b1.py", line 3, in <module>
print(A[i], end = "")
IndexError: list index out of range
Python Script

Nguyên nhân: Danh sách A chỉ có 4 phần tử (chỉ số 0-3) nhưng vòng lặp chạy đến chỉ số 4

Trường hợp 4: Lỗi logic (Logic Error)

Chương trình thực hiện bình thường nhưng kết quả không đúng với yêu cầu của bài toán. Đây là lỗi logic bên trong chương trình.

Ví dụ: Tính tổng của ba số nguyên dương đầu tiên

s = 0
for i in range(3):
    s = s + i
print(s)  # Kết quả: 3
Python Script

Phân tích:

  • Kết quả mong đợi: 1 + 2 + 3 = 6
  • Kết quả thực tế: 0 + 1 + 2 = 3
  • Nguyên nhân: range(3) tạo ra 0, 1, 2 thay vì 1, 2, 3

2. Phân loại lỗi

1. Lỗi cú pháp (Syntax Error):

  • Vi phạm quy tắc viết code của ngôn ngữ lập trình
  • Chương trình không thể chạy
  • Ví dụ: thiếu dấu :, sai từ khóa, thụt lề sai

2. Lỗi ngoại lệ (Runtime Error):

  • Cú pháp đúng nhưng xảy ra lỗi khi chạy
  • Ví dụ: ValueError, IndexError, TypeError, ZeroDivisionError

3. Lỗi logic (Logic Error):

  • Chương trình chạy bình thường nhưng kết quả sai
  • Khó phát hiện nhất vì không có thông báo lỗi
  • Cần kiểm tra kết quả với nhiều bộ dữ liệu
🧩

3. Luyện tập (Practice)

Bài tập thực hành

Bài tập 1: Nhận biết lỗi

Hãy xác định loại lỗi của các đoạn chương trình sau:

a) for i in range(5) print(i)

  • Loại lỗi: Syntax Error
  • Nguyên nhân: Thiếu dấu hai chấm (:) sau for

b) A = [1, 2, 3]; print(A[3])

  • Loại lỗi: IndexError
  • Nguyên nhân: Danh sách chỉ có chỉ số 0, 1, 2

c) x = "5"; y = 3; print(x + y)

  • Loại lỗi: TypeError
  • Nguyên nhân: Không thể cộng xâu với số

d) s = 0; for i in range(5): s = s + i; print(s) (mong đợi tính tổng 1+2+3+4+5)

  • Loại lỗi: Logic Error
  • Nguyên nhân: range(5) tạo ra 0,1,2,3,4 thay vì 1,2,3,4,5

Bài tập 2: Sửa lỗi cú pháp

Sửa các lỗi cú pháp trong đoạn chương trình sau:

Code có lỗi:

def tinh_tong(a b)
    return a + b
Python Script

Code đã sửa:

def tinh_tong(a, b):
    return a + b
Python Script

Bài tập 3: Sửa lỗi logic

Đoạn chương trình sau tính tổng các số chẵn từ 1 đến n nhưng ra kết quả sai. Hãy tìm và sửa lỗi:

Code có lỗi:

def tong_chan(n):
    s = 0
    for i in range(n):
        if i % 2 == 0:
            s = s + i
    return s
Python Script

Phân tích: range(n) tạo ra 0 đến n-1, nên tính cả số 0

Code đã sửa:

def tong_chan(n):
    s = 0
    for i in range(1, n + 1):  # Bắt đầu từ 1
        if i % 2 == 0:
            s = s + i
    return s
Python Script

Bài tập 4: Xử lý lỗi nhập liệu

Viết chương trình nhập số nguyên dương, nếu người dùng nhập sai thì yêu cầu nhập lại.

Gợi ý:

while True:
    try:
        n = int(input("Nhập số nguyên dương: "))
        if n > 0:
            break
        else:
            print("Vui lòng nhập số > 0!")
    except ValueError:
        print("Vui lòng nhập số nguyên!")

print("Bạn đã nhập:", n)
Python Script
🌟

4. Vận dụng (Application)

Bài tập vận dụng

Bài tập 1: Kiểm tra ngày tháng năm hợp lệ

Viết chương trình nhập ba số tự nhiên từ bàn phím day, month, year, các số cách nhau bởi dấu cách. Các số này biểu diễn giá trị của ngày, tháng, năm nào đó. Chương trình cần kiểm tra và in ra thông báo số liệu đã nhập vào đó có hợp lệ hay không.

Gợi ý:

def kiem_tra_ngay(day, month, year):
    # Kiểm tra năm
    if year < 1:
        return False
    
    # Kiểm tra tháng
    if month < 1 or month > 12:
        return False
    
    # Kiểm tra ngày
    if month in [1, 3, 5, 7, 8, 10, 12]:
        max_day = 31
    elif month in [4, 6, 9, 11]:
        max_day = 30
    else:  # Tháng 2
        if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0):
            max_day = 29  # Năm nhuận
        else:
            max_day = 28
    
    return 1 <= day <= max_day

# Sử dụng hàm
try:
    day, month, year = map(int, input("Nhập ngày tháng năm (cách nhau bởi dấu cách): ").split())
    if kiem_tra_ngay(day, month, year):
        print(f"{day}/{month}/{year} là ngày hợp lệ")
    else:
        print(f"{day}/{month}/{year} không phải là ngày hợp lệ")
except ValueError:
    print("Vui lòng nhập 3 số nguyên!")
except:
    print("Dữ liệu nhập không đúng định dạng!")
Python Script

Bài tập 2: Chương trình quản lý điểm với xử lý lỗi

Viết chương trình nhập điểm học sinh với các tính năng:

  • Nhập điểm môn học (0-10)
  • Kiểm tra điểm hợp lệ
  • Tính điểm trung bình
  • Xếp loại học lực

Gợi ý:

def nhap_diem(mon_hoc):
    while True:
        try:
            diem = float(input(f"Nhập điểm {mon_hoc}: "))
            if 0 <= diem <= 10:
                return diem
            else:
                print("Điểm phải trong khoảng 0-10!")
        except ValueError:
            print("Vui lòng nhập số!")

def tinh_dtb(diem_list):
    return sum(diem_list) / len(diem_list)

def xep_loai(dtb):
    if dtb >= 8:
        return "Giỏi"
    elif dtb >= 6.5:
        return "Khá"
    elif dtb >= 5:
        return "Trung bình"
    else:
        return "Yếu"

# Chương trình chính
mon_hoc = ["Toán", "Lý", "Hóa", "Văn", "Anh"]
diem_list = []

for mon in mon_hoc:
    diem = nhap_diem(mon)
    diem_list.append(diem)

dtb = tinh_dtb(diem_list)
xl = xep_loai(dtb)

print(f"Điểm trung bình: {dtb:.2f}")
print(f"Xếp loại: {xl}")
Python Script

Bài tập 3: Gỡ lỗi chương trình tính UCLN, BCNN

Viết hàm có hai tham số đầu vào là m, n. Đầu ra trả lại hai giá trị là:

  • UCLN của m, n
  • Bội chung nhỏ nhất (BCNN) của m, n

Gợi ý: Sử dụng công thức UCLN(m, n) × BCNN(m, n) = m × n

def ucln(a, b):
    while b != 0:
        a, b = b, a % b
    return a

def bcnn(a, b):
    return abs(a * b) // ucln(a, b)

def tinh_ucln_bcnn(m, n):
    return ucln(m, n), bcnn(m, n)

# Sử dụng hàm
try:
    m = int(input("Nhập số thứ nhất: "))
    n = int(input("Nhập số thứ hai: "))
    
    if m == 0 or n == 0:
        print("Không thể tính UCLN, BCNN với số 0!")
    else:
        u, b = tinh_ucln_bcnn(m, n)
        print(f"UCLN({m}, {n}) = {u}")
        print(f"BCNN({m}, {n}) = {b}")
except ValueError:
    print("Vui lòng nhập số nguyên!")
except Exception as e:
    print(f"Đã xảy ra lỗi: {e}")
Python Script

Thảo luận:

  • Tại sao việc xử lý lỗi lại quan trọng trong lập trình?
  • Làm thế nào để chương trình của em "bền" hơn khi người dùng nhập dữ liệu?
  • Khi nào nên dùng try...except và khi nào nên dùng if...else để kiểm tra?

Ghi nhớ kiến thức 🎯

  • ✅ Syntax Error: Lỗi cú pháp, chương trình không chạy được.
  • ✅ Runtime Error: Lỗi khi chạy, có thông báo rõ ràng.
  • ✅ Logic Error: Lỗi logic, chương trình chạy nhưng kết quả sai.
  • ✅ Dùng try...except để xử lý các lỗi ngoại lệ.
  • ✅ Luôn kiểm tra dữ liệu đầu vào để tránh lỗi.
  • ✅ Logic Error là loại lỗi nguy hiểm nhất cần kiểm thử kỹ.

Chúc mừng bạn đã hoàn thành bài học này! 🏆