Phụ lục: Gỡ lỗi

Trở về Mục lục cuốn sách

Những kiểu lỗi khác nhau có thể xảy ra trong chương trình, và việc phân biệt chúng rất có ích để giúp tìm được lỗi nhanh hơn:

  • Các lỗi cú pháp thường được Python báo khi nó dịch từ mã lệnh sang mã byte. Các lỗi loại này thường để chỉ rằng có điều gì đó không ổn trong cú pháp của chương trình. Chẳng hạn: Quên mất dấu hai chấm ở cuối dòng lệnh def sẽ cho ra một thông báo lỗi có phần dư thừa SyntaxError: invalid syntax.
  • Các lỗi thực thi được trình thông dịch báo nếu có điều không ổn khi chương trình đang chạy. Hầu hết các thông báo lỗi thực thi đều kèm theo thông tin về vị trí lỗi xảy ra và những hàm nào đã được thực hiện. Ví dụ: Một phép đệ quy vô hạn cuối cùng sẽ gây ra lỗi thực thi “maximum recursion depth exceeded”.
  • Các lỗi ngữ nghĩa là những vấn đề với chương trình được chạy mà không phát sinh thông báo lỗi nhưng không làm đúng công việc như đã định. Chẳng hạn: Một biểu thức không được tính theo thứ tự mà bạn trông đợi và cho kết quả không chính xác.

Bước đầu trong quá trình gỡ lỗi là hình dung ra loại lỗi nào mà bạn cần giải quyết. Mặc dù các mục tiếp sau đây được tổ chức theo loại lỗi, song những kĩ thuật có thể được dùng để giải quyết nhiều trường hợp.

Lỗi cú pháp

Các lỗi cú pháp thường dễ sửa một khi bạn đã hình dung ra chúng. Không may là những thông báo lỗi thường không giúp ích nhiều. Những dòn thông báo thường gặp nhất là SyntaxError: invalid syntaxSyntaxError: invalid token, cả hai đều không cung cấp nhiều thông tin.

Tuy nhiên dòng thông báo cũng cho bạn biết rắc rối xảy ra ở đâu trong chương trình. Thực ra, nó cho bán biết nơi mà Python phát hiện ra vấn đề, vốn không nhất thiết chính là nơi lỗi xảy ra. Đôi khi lỗi xuất hiện trước vị trí của thông báo lỗi, thường là ngay ở dòng trước.

Nếu bạn xây dựng chương trình dần từng bước, bạn hẳn đã phán đoán hợp lí vị trí xảy ra lỗi. Nó sẽ ở dòng lệnh bạn vừa thêm vào.

Nếu bạn sao chép mã lệnh từ một quyển sách, hãy bắt đầu bằng việc so sánh cẩn thận mã lệnh của bạn với mã lệnh trong cuốn sách. Kiểm tra từng kí tự một. Đồng thời nhớ rằng sách cũng có thể sai, vì vậy nếu bạn thấy có chỗ giống như lỗi, thì hoàn toàn có thể vậy.

Sau đây là một số cách tránh các lỗi cú pháp thông dụng nhất:

  1. Hãy chắc rằng bạn không dùng một từ khoá Python làm tên biến.
  2. Kiểm tra xem bạn có kèm theo dấu hai chấm ở lệnh đầu các lệnh phức hợp chưa, bao gồm các lệnh for, while, if, và def.
  3. Hãy chắc rằng các chuỗi trong mã lệnh đều có đủ cặp nháy kép.
  4. Nếu bạn có chuỗi rải trên nhiều dòng với cặp ba dấu nháy (nháy đơn hoặc nháy kép), hãy chắc rằng bạn có kết thúc chuỗi một cách đúng đắn. Một chuỗi bỏ lửng có thể gây ra lỗi invalid token ở điểm cuối chương trình, hoặc coi phần còn lại của chương trình như một chuỗi đến khi nó bắt gặp chuỗi tiếp theo. Trong trường hợp thứ hai, nó thậm chí còn không báo lỗi gì!
  5. Một toán tử mở ngoặc—(, {, hay [—mà quên được đóng sẽ làm cho Python chạy tiếp lấy dòng bên dưới làm một phần của câu lệnh hiện hành. Thường thì lỗi sẽ xuất hiện ngay ở dòng kế tiếp.
  6. Kiểm tra lỗi kinh điển xảy ra khi dùng = thay vì == trong câu lệnh điều kiện.
  7. Kiểm tra sự thụt đầu dòng để đảm bảo tính đúng đắn. Python có thể xử lý các dấu cách và dấu tab, nhưng nếu bạn dùng lẫn cả hai loại có thể sẽ có vấn đề. Cách tốt nhất để tránh điều này là dùng một trình soạn văn bản chữ có thể nhận ra ngôn ngữ Python và tự căn lề một cách thống nhất.

Nếu các biện pháp trên đều không có tác dụng, hãy đọc mục tiếp theo…

Tôi vẫn tiếp tục sửa đổi mà chẳng thấy gì khác.

Nếu trình thông dịch báo rằng có lỗi và bạn không nhìn ra thì có thể vì bạn và trình thông dịch không nhìn vào cùng một đoạn mã. Hãy kiểm tra lại môi trường lập trình của bạn để chắc rằng chương trình mà bạn đang soạn thảo cũng chính được chạy bởi Python.

Nếu bạn không chắc chắn, hãy thử cố ý đưa vào một lỗi cú pháp hiển nhiên vào ngay đầu chương trình. Bây giờ chạy lại chương trình. Nếu trình thông dịch không tìm thấy lỗi mới thì rõ ràng là bạn không chạy đoạn mã lệnh mới.

Sau đây là một số trường hợp sai lầm dễ gặp:

  • Bạn đã soạn thảo file mà lại quên lưu vào trước khi chạy lại. Một số môi trường lập trinh giúp bạn làm điều này, nhưng số khác thì không.
  • Bạn đổi tên file, nhưng vẫn chạy chương trình có tên cũ.
  • Một chi tiết trong môi trường phát triển bị thiết lập sai.
  • Nếu bạn đang viết một module và dùng lệnh import, hãy chắc rằng bạn không đặt tên module giống như một trong những module tiêu chuẩn của Python.
  • Nếu bạn đang dùng import để đọc một module, hãy nhớ rằng bạn phải khởi động lại trình thông dịch hoặc dùng reload để đọc một file đã bị chỉnh sửa. Còn nếu bạn nhập lại module thì máy sẽ chẳng làm gì.

Nếu bạn bị bí và không thể hình dung được chuyện gì đang xảy ra, một cách là bắt đầu lại từ đầu với một chương trình kiểu như “Hello, World!”, và chắc rằng bạn biết cách chạy một chương trình có sẵn. Sau đó dần thêm từng phần của chương trình cần chạy vào chương trình mới này.

Lỗi thực thi

Một khi chương trình của bạn đã đúng về mặt cú pháp, Python có thể biên dịch nó và ít nhất là bắt đầu chạy nó. Điều gì có thể trục trặc nữa?

Chương trình của tôi hoàn toàn không làm gì.

Vấn đề này thường gặp nhất khi file của bạn có chứa các hàm và lớp nhưng không thực sự kích hoạt gì để bắt đầu thực hiện tính toán. Có thể điều này được định sẵn nếu bạn chỉ nhập module này để cung cấp các lớp và hàm.

Nhưng nếu không phải vì lí do đinh sẵn, thì hãy chắc rằng bạn đã gọi một hàm để thực hiện tính toán, hoặc thực thi nó từ dấu nhắc lệnh. Ngoài ra, cũng xem thêm mục “Luồng thực hiện” tiếp theo.

Chương trình bị treo.

Nếu một chương trình dừng lại và hình như không làm gì, nó đã bị “treo”. Thường thì điều này nghĩa là nó mắc phải một vòng lặp vô hạn hoặc đệ quy vô hạn.

  • Nếu có một vòng lặp cụ thể mà bạn nghi ngờ có vấn đề, hãy thêm một lệnh print ngay trước vòng lặp, để in ra “tien vao vong lap” và một lệnh khác ngay sau vòng lặp, in ra “thoat khoi vong lap”.

    Chạy chương trình. Nếu bạn thấy được thông điệp thứ nhất mà không thấy cái thứ hai thì đã có một vòng lặp vô hạn. Xem tiếp mục “Vòng lặp vô hạn” dưới đây.

  • Ở hầu hết trường hợp, đệ quy vô hạn sẽ làm cho chương trình chạy một lúc và sau đo hiện ra lỗi “RuntimeError: Maximum recursion depth exceeded”. Nếu điều này xảy ra, hãy xem tiếp mục “Đệ quy vô hạn” sau đây.

    Nếu bạn không gặp phải lỗi này nhưng nghi ngờ rằng có vấn đề xảy ra với một phương thức hoặc hàm đệ quy, bạn vẫn có thể sử dụng các kĩ thuật trong mục “Đệ quy vô hạn”.

  • Nếu không cách nào trong số trên có tác dụng, hãy thử những hàm và phương thức khác có chứa vòng lặp hoặc đệ quy.
  • Nếu cách này cũng không có tác dụng thì có thể là bạn chưa hiểu luồng thực hiện của chương trình. Hãy đọc tiếp mục “Flow of Execution” bên dưới.

Vòng lặp vô hạn

Nếu bạn nghĩ rằng bạn có một vòng lặp vô hạn và cho rằng mình đã biết được vòng lặp nào gây ra vấn đề, thì hãy thêm một lệnh print tại điểm cuối vòng lặp và in ra giá trị các biến trong điều kiện cùng với giá trị của điều kiện.

Chẳng hạn:

while x > 0 and y < 0 :
    # thao tac voi x
    # thao tac voi y

    print  "x: ", x
    print  "y: ", y
    print  "dieu kien: ", (x > 0 and y < 0)

Bây giờ khi chạy chương trình, bạn sẽ thấy ba dòng kết quả với mỗi lần chạy qua vòng lặp. Lần cuối cùng chạy qua vòng lặp điều kiện sẽ phải là false. Nếu vòng lặp tiếp tục chạy, bạn sẽ nhìn được các giá trị của xy, và có thể hình dung được tại sao chúng không được cập nhật đúng.

Đệ quy vô hạn

Trong nhiều trường hợp, một vòng lặp đệ quy sẽ khiến chương trình chạy một lúc và sau đó báo lỗi Maximum recursion depth exceeded.

Nếu bạn nghi ngờ rằng một hàm hoặc phương thức nào đó gây ra đệ quy vô hạn, hãy bắt đàu kiểm tra để chắc rằng có một trường hợp cơ sở. Nói cách khác, cần phải có điều kiện nào đó để khiến cho hàm hoặc phương thức trả về mà không gọi đệ quy nữa. Nếu không, bạn cần phải nghĩ lại thuật toán và tìm ra một trường hợp cơ sở.

Nếu có một trường hợp cơ sở nhưng chương trình dường như không đạt đến đó, thì hãy thêm câu lệnh print vào điểm đầu của hàm hoặc phương thức để in ra các tham biến. Bây giờ khi chạy chương trình, bạn sẽ thấy một ít dòng kết quả mỗi lần hàm hoặc phương thức được gọi đến, và sẽ thấy ccasc tham biến. Nếu tham biến không thay đổi với xu hướng về trường hợp cơ sở, bạn sẽ có được nhận định về nguyên nhân tại sao.

Luồng thực hiện

Nếu bạn không chắc chắn về luồng thực hiện trong chương trình, hãy thêm các câu lệnh print vào điểm đầu của mỗi hàm với thông báo kiểu như “bat dau ham foo”, trong đó foo là tên hàm.

Bây giờ khi chạy chương trình, nó sẽ in ra một dấu vết của mỗi hàm khi được gọi đến.

Khi chạy chương trình tôi nhận được một biệt lệ.

Nếu trong quá trình chạy có trục trặc xảy ra, Python sẽ in một thông báo trong đó có tên của biệt lệ, dòng lệnh có vấn đề, và một dò ngược.

Thông báo dò ngược nhằm chỉ định hàm đang được chạy, và hàm gọi nó, rồi hàm gọi hàm đó, và cứ như vậy. Nói cách khác, nó dò theo một dãy các lời gọi hàm để đến nơi có trục trặc. Nó cũng có chứa số thứ tự dòng trong file nơi mà những lời gọi hàm này diễn ra.

Bước đầu tiên là kiểm tra vị trí trong chương trình nơi mà lỗi xuất hiện đòng thời thử hình dung điều gì đã xảy ra. Sau đây là một số lỗi thực thi thường gặp nhất:

NameError:
Bạn đang cố gắng dùng một biến không tồn tại trong môi trường hiện hành. Hãy nhớ rằng các biến địa phương chỉ có ý nghĩa cục bộ. Bạn không thể nhắc đến chúng từ bên ngoài hàm mà chúng được định nghĩa.

TypeError:
Sau đây là một số lí do khả dĩ:

  • Bạn đang cố thử dùng một giá trị không đúng cách. Chẳng hạn: lấy chỉ số của một chuỗi, danh sách, hoặc bộ mà dùng kiểu số liệu không phải số nguyên.
  • Có sự bất đồng giữa các mục bên trong một chuỗi định dạng và các mục được truyền vào để chuyển đổi. Điều này có thể xảy ra khi số các mục không bằng nhau, hoặc thao tác chuyển đổi không hợp lệ.
  • Bạn đang truyền một số lượng không đúng các đối số vào trong hàm hoặc phương thức. Với phương thức, hãy xem định nghĩa cảu nó và kiểm tra rằng tham biến đầu tiên phải là self. Sau đó nhìn vào lời gọi phương thức; hãy chắc rằng bạn gọi phuonwg thức với đối tượng có kiểu phù hợp và đã cung cấp các đối số khác một cách đúng đắn.
KeyError:
Bạn đang cố gắng truy cập một phần tử của từ điển bằng một khóa mà từ điển đó không có.

AttributeError:
Bạn đang cố gắng truy cập một thuộc tính hoặc phương thức mà chúng không tồn tại. Hãy kiểm tra tên chữ! Bạn có thể dùng dir để liệt kê những thuộc tính hiện có.

Nếu một AttributeError nói rằng đối tượng có kiểu NoneType, điều đó nghĩa là nó là None. Một nguyên nhân thông thường là quên không trả về giá trị từ một hàm; nếu bạn đã đến điểm cuối của hàm mà không gặp phải câu lệnh return, nó sẽ trả về None. Một lí do thường gặp khác là việc dùng kết quả từ một phương thức với danh sách, như sort, vốn trả về None.

IndexError:
Chỉ số mà bạn đang dùng để truy cập một danh sách, chuỗi, hoặc bộ lại lớn hơn chiều dài của nó trừ đi một. Ngay trước điểm gây ra lỗi, hãy thêm vào câu lệnh print để hiển thị giá trị của chỉ số cùng với chiều dài của dãy. Liệu dãy này có kích thước đúng chưa? Chỉ số có đúng không?

Bộ gỡ lỗi (pdb) của Python sẽ giúp ích cho việc dò ra các biệt lệ vì chúng cho phép bạn kiểm tra trạng thái của chương trình ngay trước khi có lỗi. Bạn có thể đọc thêm về pdbdocs.python.org/lib/module-pdb.html.

Tôi thêm vào quá nhiều lệnh print đến nỗi bây giờ tràn ngập kết quả đầu ra.

Một trong những vấn đề khi dùng lệnh print để gỡ lỗi là việc bạn có thể bị chìm trong kết quả ra. Có hai cách tiếp tục: đơn giản hóa đầu ra hoặc đơn giản hóa chương trình.

Để giản hóa đầu ra, bạn cần xóa bỏ hoặc đưa vào chú thích những dòng lệnh print vốn không có tác dụng, hoặc kết hợp chúng lại, hoặc sửa định dạng đầu ra để dễ hiểu hơn.

Để giản hóa chương trình, có vài cách làm được. Trước hết, hãy giảm quy mô của bài toán xuống. Chẳng hạn, nếu bạn cần tìm kiếm trong danh sách, hãy làm với danh sách nhỏ. Nếu chương trình nhận đầu vào từ phía người dùng, hãy cho những dữ liệu vào đơn giản mà gây ra lỗi.

Thứ hai là dọn dẹp chương trình. Hãy bỏ những đoạn mã chết và tổ chức lại chương trình để nó càng dễ đọc càng tốt. Chẳng hạn, nếu bạn nghi rằng vấn đề nằm ở một đoạn nằm sâu trong chương trình, hãy thử viết lại nó với cấu trúc đơn giản hơn. Nếu bạn nghi ngờ rằng có một hàm lớn, hãy thử chẻ nhỏ thành những hàm con và kiểm tra lần lượt.

Thông thường quá trình tìm ra trường hợp thử đơn giản nhất sẽ dẫn bạn đến điểm gây lỗi. Nếu bạn thấy được chương trình chạy được trong một trường hợp nhưng không được trong trường hợp khác, điều đó sẽ là dấu vết cho thấy điều gì đang diễn ra.

Tương tự như vậy, việc viết lại một đoạn mã có thể giúp bạn phát hiện những lỗi nhỏ. Nếu bạn thực hiện sửa đổi mà nghĩ rằng nó không ảnh hưởng gì đến chương trình, và lúc có ảnh hưởng thì đó sẽ là bài học cho bạn.

Lỗi ngữ nghĩa

Theo khía cạnh nhất định, lỗi ngữ nghĩa là thứ khó gỡ nhất, vì trình thông dịch không cung cấp thông tin gì về sự trục trặc. Chỉ có bạn mới biết rằng chương trinh cần phải thực hiện điều gì.

Bước đầu tiên là tạo lập một kết nối giữa nội dung chương trình và biểu hiện mà bạn quan sát được. Bạn cần giả thiết về điều thật sự mà chương trình đang thực hiện. Một trong những yếu tố làm việc này trở nên khó khăn là máy tính chạy quá nhanh.

Bạn sẽ thường muốn làm chậm chương trình lại ngang bằng tốc độ của người, và dùng một số bộ gỡ lỗi nếu có thể. Nhưng thời gian càn thiết để chèn thêm một vài lệnh print đúng chỗ thường ngắn hơn so với việc thiết lập bộ gỡ lỗi, chèn thêm và gỡ bỏ các điểm dừng, và “lần bước” tới điểm xảy ra lỗi trong chương trình.

Chương trình tôi viết không hoạt động đúng.

Bạn cần tự hỏi mình những điều sau:

  • Có điều gì mà chương trình cần phải làm nhưng dường như nó không làm hay không? Hãy tìm ra đoạn mã lệnh thực hiện tính năng đó và chắc rằng nó được thực thi khi bạn nghĩ rằng lẽ ra nó phải chạy.
  • Có điều gì đang diễn ra mà lẽ ra không nên có nó? Hãy tìm đoạn mã trong chương trình mà thực hiện tính năng đó rồi xem liệu nó có được thực khi trong khi đáng lẽ thì không.
  • Có đoạn mã nào tạo ra một hiệu ứng mà không như bạn mong đợi không? Hãy chắc rằng bạn hiểu được đoạn mã nghi vấn, đặc biệt khi nó liên quan đến lời gọi các hàm hoặc phương thức trong module Python khác. Hãy đọc các tài liệu về hàm mà bạn đã gọi. Thử dùng chúng bằng cách viết các trường hợp kiểm tra đơn giản và xem xét kết quả.

Để lập trình, bạn phải có một mô hình tưởng tượng về cách thức hoạt động của chương trình. Nếu bạn viết một chương trình mà không thực hiện đúng việc bạn mong đợi, thì thường là vấn đề không nằm ở chương trình; nó nằm ở mô hình tưởng tượng của bạn.

Cách tốt nhất để sửa mô hình tưởng tượng cho đúng là chia chương trình thành những bộ phận (thường là các hàm và phương thức) rồi kiểm tra chạy thử từng bộ phận một cách độc lập. Một khi bạn thấy sự khác biệt giữa mô hình và thực tế, bạn sẽ có thể giải quyết vấn đề.

Tất nhiên, bạn cần phải xây dựng và chạy thử các bộ phận song song với việc phát triển chương trình. Nếu bạn gặp vướng mắc, hẳn chỉ có một phần rất nhỏ những mã lệnh mới đưa vào mà bạn không chắc rằng nó đúng.

Tôi có một biểu thức lớn và gai góc mà chẳng hoạt động theo sự mong đợi.

Việc viết những biểu thức phức tạp cũng tốt miễn là chúng dễ đọc, nhưng chúng có thể làm việc gỡ lỗi gặp khó khăn. Thông thường nên chẻ nhỏ một biểu thức thành một loạt các lệnh gán cho những biến tạm thời.

Chẳng hạn:

self.hands[i].addCard(self.hands[self.findNeighbor(i)].popCard())

Đoạn này có thể được viết lại thành:

neighbor = self.findNeighbor(i)
pickedCard = self.hands[neighbor].popCard()
self.hands[i].addCard(pickedCard)

Dạng mã lệnh chi tiết thì dễ đọc hơn vì tên biến cho ta bản thân đã giúp giải thích rõ thêm, và cũng dễ gỡ lỗi hơn vì bạn có thể kiểm tra kiểu của những biến trung gian cùng việc hiển thị giá trị của chúng.

Một vấn đề khác có thể xảy ra với những biểu thức lớn là thứ tự thực hiện phép tính có thể không như bạn mong muốn. Chẳng hạn, nếu bạn dịch biểu thức x / 2π sang ngôn ngữ Python, có thể bạn đã viết:

y = x / 2 * math.pi

Điều này không đúng vì các phép nhân và chia có cùng thứ tự ưu tiên và được lượng giá từ trái sang phải. Vì vậy biểu thức này sẽ tính xπ / 2.

Một cách hay để gỡ lỗi biểu thức là thêm vào những cặp ngoặc đơn để giúp cho thứ tự lượng giá được rõ ràng:

 y = x / (2 * math.pi)

Mỗi khi bạn không nắm vững thứ tự ước lượng, hãy dùng cặp ngoặc đơn. Chúng không chỉ giúp chương trình đúng đắn hơn (theo nghĩa thực hiện công việc bạn mong đợi), mà còn giúp người khác dễ đọc hơn mà không phải ghi nhớ quy luật thứ tự ưu tiên.

Tôi có một hàm hoặc phương thức không trả về giá trị được mong đợi.

Với lệnh return kèm theo một biểu thức phức tạp, bạn không có cơ hội in ra giá trị trước khi được rả về. Một lần nữa, hãy dùng biến tạm thời. Chẳng hạn, thay vì:

return self.hands[i].removeMatches()

bạn có thể viết:

count = self.hands[i].removeMatches()
return count

Bây giờ bạn đã có cơ hội hiển thị giá trị của count trước khi trả về.

Thật sự tôi rất, rất vướng mắc và cần được giúp đỡ.

Trước hết, hãy thử rời khỏi máy tính trong vài phút. Máy tính phát ra sóng từ gây ảnh hưởng đến não, với các triệu chứng sau:

  • Cáu giận.
  • Tin tưởng vào lực siêu nhiên (“máy tính này ghét tôi”) và những ảo tưởng (“chương trình chỉ chạy khi tôi đội ngược mũ”).
  • Lập trình bước ngẫu nhiên (nỗ lực lập trình bằng cách viết tất cả các trường hợp chương trình có thể có và chọn ra một phiên bản hoạt động đúng).

Nếu bạn tự thấy mình mắc phải một trong số các triệu chứng trên, hãy đứng dậy và đi dạo. Khi đã tĩnh tâm hẳn, hãy nghĩ lại chương trình. Nó đang làm điều gì? Đâu là các nguyên nhân gây ra biểu hiện đó? Lần cuối cùng chương trình cọn chạy được là lúc nào, và sau đó bạn thực hiện những điều gì?

Đôi khi phát hiện lỗi chỉ là vấn đề thời gian. Tôi thường tìm thấy lỗi trong lúc rời xa khỏi máy tính và để trí óc khuây khỏa. Một số nơi tốt nhất để thoát khỏi máy gồm có trên tàu, khi đi tắm, và trước khi đi ngủ.

Không, tôi thật sự muốn giúp đỡ.

Điều đó xảy ra. Ngay cả những lập trình viên giỏi nhất đôi lúc cũng bị bí. Đôi khi bạn làm một chương trình lâu quá đến nỗi không thể phát hiện ra lỗi. Tìm một người có góc nhìn khác chính là điều cần thiết.

Trước khi yêu cầu giúp đỡ, bạn hãy chuẩn bị kĩ. Chương trình phải càng đơn giản càng tốt, và hãy phân tích trên dữ liệu đầu vào nhỏ nhất có thể gây lỗi. Bạn cần có các lệnh print ở những vị trí thích hợp (và kết quả đầu ra phải dễ hiểu). Bạn cần hiểu rõ vấn đề để có thể diễn đạt nó một cách ngắn gọn.

Khi đưa người đến giúp, hãy chắc chắn rằng bạn cung cấp đủ thông tin mà họ cần:

  • Nếu có thông báo lỗi, thông báo đó là gì và nó chỉ định phần nào trong chương trình?
  • Việc cuối cùng mà bạn thao tác trước khi lỗi này xảy ra là gì? Những dòng lệnh nào bạn vừa mới viết gần đây nhất, hay trường hợp chạy thử gần đây nhất mới bị thất bại là gì?
  • Bạn đã thử những biện pháp gì rồi, và thu hoạch được gì?

Khi bạn tìm thấy lỗi, hãy nghĩ trong giây lát xem bằng cách nào có thể giúp bạn tìm ra nó nhanh hơn không. Lần tiếp theo khi bạn thấy điều tương tự, có thể bạn sẽ chóng phát hiện ra lỗi hơn.

Nhớ rằng mục tiêu không chỉ có làm cho chương trình chạy được. Mục tiêu là học cách làm cho chương trình chạy được.

8 bình luận

Filed under Think Python

8 responses to “Phụ lục: Gỡ lỗi

  1. Với phần phụ lục này, cuốn sách Think Python khép lại ở đây. Hi vọng là bạn đọc sẽ tìm được những thông tin bổ ích từ cuốn sách này.
    Mọi ý kiến góp ý về nội dung và chất lượng dịch, bạn có thể gửi các comment bên dưới từng bài post của từng chương. Tôi sẽ cố gắng trả lời thỏa đáng những câu hỏi và yêu cầu của các bạn.
    Chúc các bạn một năm mới có nhiều niềm vui và dồi dào sức khỏe.

  2. Pingback: Think Python: Cách tư duy như nhà khoa học máy tính | Blog của Chiến

  3. Pingback: Think Java: Cách suy nghĩ như nhà khoa học máy tính | Blog của Chiến

  4. Ẩn danh

    Hiện tại em đã học đến chương 18 của loạt bài này. Thật sự rất cảm ơn anh Quang Chiến, cộng đồng rất cần những người như anh. Hy vọng sẽ được gặp anh trong một ngày không xa!

    • Rất mừng khi biết bạn quan tâm đến các ngôn ngữ lập trình “ít” được giảng dạy chính thống ở Việt Nam như Python. Hi vọng trong tương lai tôi có thể dịch thêm những tài liệu tiếng Anh bổ ích khác.

  5. Pingback: Think Python: Cách tư duy như nhà khoa học máy tính » Book Python

Bình luận về bài viết này