Bài 7.2. Python - Giới thiệu vòng lặp while

Vòng lặp for lấy một tập hợp các mục và thực thi một khối mã một lần cho mỗi mục trong tập hợp. Ngược lại, vòng lặp while chạy miễn là, hoặc trong khi, một điều kiện nhất định là đúng.

Vòng lặp while trong hành động

Bạn có thể sử dụng vòng lặp while để đếm lên qua một loạt các số. Ví dụ, vòng lặp while sau đây đếm từ 1 đến 5:

current_number = 1
while current_number <= 5:
    print(current_number)
    current_number += 1

Trong dòng đầu tiên, chúng ta bắt đầu đếm từ 1 bằng cách gán giá trị 1 cho current_number. Vòng lặp while sau đó được đặt để tiếp tục chạy miễn là giá trị của current_number nhỏ hơn hoặc bằng 5. Mã bên trong vòng lặp in ra giá trị của current_number và sau đó cộng thêm 1 vào giá trị đó với current_number += 1. (Toán tử += là cách viết tắt cho current_number = current_number + 1.)

Python lặp lại vòng lặp miễn là điều kiện current_number <= 5 là đúng. Vì 1 nhỏ hơn 5, Python in ra 1 và sau đó cộng thêm 1, làm cho số hiện tại là 2. Vì 2 nhỏ hơn 5, Python in ra 2 và lại cộng thêm 1, làm cho số hiện tại là 3, và cứ tiếp tục như vậy. Khi giá trị của current_number lớn hơn 5, vòng lặp dừng chạy và chương trình kết thúc:

1
2
3
4
5

Các chương trình bạn sử dụng hàng ngày có thể chứa các vòng lặp while. Ví dụ, một trò chơi cần một vòng lặp while để tiếp tục chạy miễn là bạn muốn tiếp tục chơi, và để nó có thể dừng chạy ngay khi bạn yêu cầu thoát. Các chương trình sẽ không thú vị nếu chúng dừng chạy trước khi chúng ta yêu cầu hoặc tiếp tục chạy ngay cả khi chúng ta muốn thoát, vì vậy các vòng lặp while rất hữu ích.

Để người dùng chọn khi nào thoát

Chúng ta có thể làm cho chương trình parrot.py chạy lâu như người dùng muốn bằng cách đặt hầu hết chương trình bên trong một vòng lặp while. Chúng ta sẽ định nghĩa một giá trị thoát và sau đó giữ cho chương trình chạy miễn là người dùng chưa nhập giá trị thoát:

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
message = ""
while message != 'quit':
    message = input(prompt)
    print(message)

Đầu tiên, chúng ta định nghĩa một lời nhắc cho người dùng biết hai tùy chọn của họ: nhập một thông điệp hoặc nhập giá trị thoát (trong trường hợp này là 'quit'). Sau đó, chúng ta thiết lập một biến message để theo dõi bất kỳ giá trị nào người dùng nhập. Chúng ta định nghĩa message là một chuỗi trống, "", để Python có cái gì đó để kiểm tra lần đầu tiên nó đạt đến dòng while. Lần đầu tiên chương trình chạy và Python đạt đến câu lệnh while, nó cần so sánh giá trị của message với 'quit', nhưng chưa có đầu vào nào từ người dùng. Nếu Python không có gì để so sánh, nó sẽ không thể tiếp tục chạy chương trình. Để giải quyết vấn đề này, chúng ta đảm bảo gán cho message một giá trị ban đầu. Mặc dù chỉ là một chuỗi trống, nó sẽ có ý nghĩa với Python và cho phép nó thực hiện so sánh làm cho vòng lặp while hoạt động. Vòng lặp while này chạy miễn là giá trị của message không phải là 'quit'.

Lần đầu tiên qua vòng lặp, message chỉ là một chuỗi trống, vì vậy Python vào vòng lặp. Tại message = input(prompt), Python hiển thị lời nhắc và chờ người dùng nhập đầu vào của họ. Bất cứ điều gì họ nhập được gán cho message và in ra; sau đó, Python đánh giá lại điều kiện trong câu lệnh while. Miễn là người dùng chưa nhập từ 'quit', lời nhắc được hiển thị lại và Python chờ thêm đầu vào. Khi người dùng cuối cùng nhập 'quit', Python dừng thực thi vòng lặp while và chương trình kết thúc:

Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello everyone!
Hello everyone!
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello again.
Hello again.
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. quit
quit

Chương trình này hoạt động tốt, ngoại trừ việc nó in từ 'quit' như thể đó là một thông điệp thực sự. Một kiểm tra if đơn giản sẽ khắc phục điều này:

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
message = ""
while message != 'quit':
    message = input(prompt)
    if message != 'quit':
        print(message)

Bây giờ chương trình thực hiện một kiểm tra nhanh trước khi hiển thị thông điệp và chỉ in thông điệp nếu nó không khớp với giá trị thoát:

Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello everyone!
Hello everyone!
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello again.
Hello again.
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. quit

Sử dụng cờ

Trong ví dụ trước, chúng ta đã để chương trình thực hiện các tác vụ nhất định trong khi một điều kiện nhất định là đúng. Nhưng điều gì sẽ xảy ra với các chương trình phức tạp hơn trong đó nhiều sự kiện khác nhau có thể khiến chương trình dừng chạy?

Ví dụ, trong một trò chơi, nhiều sự kiện khác nhau có thể kết thúc trò chơi. Khi người chơi hết tàu, thời gian của họ hết, hoặc các thành phố mà họ phải bảo vệ đều bị phá hủy, trò chơi nên kết thúc. Nó cần kết thúc nếu bất kỳ một trong những sự kiện này xảy ra. Nếu nhiều sự kiện có thể xảy ra để dừng chương trình, cố gắng kiểm tra tất cả các điều kiện này trong một câu lệnh while trở nên phức tạp và khó khăn.

Đối với một chương trình chỉ nên chạy miễn là nhiều điều kiện đều đúng, bạn có thể định nghĩa một biến xác định liệu toàn bộ chương trình có đang hoạt động hay không. Biến này, được gọi là cờ, hoạt động như một tín hiệu cho chương trình. Chúng ta có thể viết các chương trình của mình để chúng chạy trong khi cờ được đặt thành True và dừng chạy khi bất kỳ sự kiện nào đặt giá trị của cờ thành False. Kết quả là, câu lệnh while tổng thể của chúng ta chỉ cần kiểm tra một điều kiện: liệu cờ hiện tại có đang là True hay không. Sau đó, tất cả các kiểm tra khác của chúng ta (để xem liệu một sự kiện đã xảy ra mà nên đặt cờ thành False) có thể được tổ chức gọn gàng trong phần còn lại của chương trình.

Hãy thêm một cờ vào parrot.py từ phần trước. Cờ này, chúng ta sẽ gọi là active (mặc dù bạn có thể gọi nó bất cứ điều gì), sẽ giám sát liệu chương trình có nên tiếp tục chạy hay không:

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
active = True
while active:
    message = input(prompt)
    if message == 'quit':
        active = False
    else:
        print(message)

Chúng ta đặt biến active thành True để chương trình bắt đầu ở trạng thái hoạt động. Làm như vậy làm cho câu lệnh while đơn giản hơn vì không có so sánh nào được thực hiện trong câu lệnh while chính nó; logic được xử lý trong các phần khác của chương trình. Miễn là biến active vẫn là True, vòng lặp sẽ tiếp tục chạy.

Trong câu lệnh if bên trong vòng lặp while, chúng ta kiểm tra giá trị của message một khi người dùng nhập đầu vào của họ. Nếu người dùng nhập 'quit', chúng ta đặt active thành False, và vòng lặp while dừng lại. Nếu người dùng nhập bất cứ điều gì khác ngoài 'quit', chúng ta in đầu vào của họ như một thông điệp.

Chương trình này có cùng đầu ra như ví dụ trước đó, nơi chúng ta đặt kiểm tra điều kiện trực tiếp trong câu lệnh while. Nhưng bây giờ chúng ta có một cờ để chỉ ra liệu toàn bộ chương trình có đang ở trạng thái hoạt động hay không, sẽ dễ dàng thêm nhiều kiểm tra hơn (chẳng hạn như các câu lệnh elif) cho các sự kiện nên khiến active trở thành False. Điều này hữu ích trong các chương trình phức tạp như trò chơi, trong đó có thể có nhiều sự kiện nên khiến chương trình dừng chạy. Khi bất kỳ sự kiện nào trong số này khiến cờ active trở thành False, vòng lặp trò chơi chính sẽ thoát, một thông báo Game Over có thể được hiển thị và người chơi có thể được cung cấp tùy chọn chơi lại.

Sử dụng break để thoát khỏi vòng lặp

Để thoát khỏi vòng lặp while ngay lập tức mà không chạy bất kỳ mã còn lại nào trong vòng lặp, bất kể kết quả của bất kỳ kiểm tra điều kiện nào, sử dụng câu lệnh break. Câu lệnh break điều hướng luồng của chương trình; bạn có thể sử dụng nó để kiểm soát dòng mã nào được thực thi và dòng nào không, để chương trình chỉ thực thi mã mà bạn muốn, khi bạn muốn.

Ví dụ, hãy xem xét một chương trình yêu cầu người dùng về các địa điểm họ đã đến thăm. Chúng ta có thể dừng vòng lặp while trong chương trình này bằng cách gọi break ngay khi người dùng nhập giá trị 'quit':

prompt = "\nPlease enter the name of a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.) "
while True:
    city = input(prompt)
    if city == 'quit':
        break
    else:
        print(f"I'd love to go to {city.title()}!")

Một vòng lặp bắt đầu với while True sẽ chạy mãi mãi trừ khi nó đạt đến một câu lệnh break. Vòng lặp trong chương trình này tiếp tục yêu cầu người dùng nhập tên các thành phố họ đã đến cho đến khi họ nhập 'quit'. Khi họ nhập 'quit', câu lệnh break chạy, khiến Python thoát khỏi vòng lặp:

Please enter the name of a city you have visited:
(Enter 'quit' when you are finished.) New York
I'd love to go to New York!
Please enter the name of a city you have visited:
(Enter 'quit' when you are finished.) San Francisco
I'd love to go to San Francisco!
Please enter the name of a city you have visited:
(Enter 'quit' when you are finished.) quit

Sử dụng continue trong vòng lặp

Thay vì thoát khỏi vòng lặp hoàn toàn mà không thực thi phần còn lại của mã trong vòng lặp, bạn có thể sử dụng câu lệnh continue để quay lại đầu vòng lặp, dựa trên kết quả của một kiểm tra điều kiện. Ví dụ, hãy xem xét một vòng lặp đếm từ 1 đến 10 nhưng chỉ in ra các số lẻ trong phạm vi đó:

current_number = 0
while current_number < 10:
    current_number += 1
    if current_number % 2 == 0:
        continue
    print(current_number)

Đầu tiên, chúng ta đặt current_number thành 0. Vì nó nhỏ hơn 10, Python vào vòng lặp while. Một khi bên trong vòng lặp, chúng ta tăng số đếm lên 1, vì vậy current_number là 1. Câu lệnh if sau đó kiểm tra modulo của current_number và 2. Nếu modulo là 0 (có nghĩa là current_number chia hết cho 2), câu lệnh continue yêu cầu Python bỏ qua phần còn lại của vòng lặp và quay lại đầu vòng lặp. Nếu số hiện tại không chia hết cho 2, phần còn lại của vòng lặp được thực thi và Python in ra số hiện tại:

1
3
5
7
9

Tránh vòng lặp vô hạn

Mỗi vòng lặp while cần một cách để dừng chạy để nó không tiếp tục chạy mãi mãi. Ví dụ, vòng lặp đếm này nên đếm từ 1 đến 5:

x = 1
while x <= 5:
    print(x)
    x += 1

Tuy nhiên, nếu bạn vô tình bỏ qua dòng x += 1, vòng lặp sẽ chạy mãi mãi:

# Vòng lặp này chạy mãi mãi!
x = 1
while x <= 5:
    print(x)

Bây giờ giá trị của x sẽ bắt đầu từ 1 nhưng không bao giờ thay đổi. Kết quả là, kiểm tra điều kiện x <= 5 sẽ luôn đánh giá là True và vòng lặp while sẽ chạy mãi mãi, in ra một loạt các số 1, như sau:

1
1
1
1
--snip--

Mỗi lập trình viên vô tình viết một vòng lặp while vô hạn từ thời gian này đến thời gian khác, đặc biệt khi các vòng lặp của chương trình có các điều kiện thoát tinh tế. Nếu chương trình của bạn bị kẹt trong một vòng lặp vô hạn, nhấn CTRL-C hoặc chỉ cần đóng cửa sổ terminal hiển thị đầu ra của chương trình.

Để tránh viết các vòng lặp vô hạn, kiểm tra mỗi vòng lặp while và đảm bảo vòng lặp dừng lại khi bạn mong đợi. Nếu bạn muốn chương trình của mình kết thúc khi người dùng nhập một giá trị đầu vào nhất định, chạy chương trình và nhập giá trị đó. Nếu chương trình không kết thúc, xem xét kỹ cách chương trình của bạn xử lý giá trị nên khiến vòng lặp thoát. Đảm bảo ít nhất một phần của chương trình có thể làm cho điều kiện của vòng lặp trở thành False hoặc khiến nó đạt đến một câu lệnh break.

Làm thêm nhiều bài tập miễn phí tại đây

Comments

There are no comments at the moment.