You are on page 1of 250

Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Phiên bản MEAP


Manning Early Access Program
Chương trình truy cập sớm Manning
Hãy nói về Python
Phiên bản 02

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Hoan nghênh

Cảm ơn bạn đã mua MEAP cho Let's Talk Python.


Cuốn sách này dựa trên một câu chuyện có thật. Con trai
Erik của tôi thích đến Starbucks và nếm thử đồ uống với
nhiều hương vị và lớp phủ (topping) khác nhau. Một
ngày nọ, cậu ta quyết định tự chuẩn bị đồ uống và chiêu
đãi bạn bè. Cậu lấy máy tính bảng cá nhân để thu thập
đơn đặt hàng từ bè bạn, nhưng tôi đề nghị tạo một
chương trình đơn giản cho việc đó. Cậu ấy đã từng học
lập trình trước đây rồi nhưng hầu hết các bài tập đều
nhàm chán quá đỗi. Lần này, cậu ấy nhìn thấy một vấn
đề thực sự mà cậu có thể giải quyết bằng lập trình và
cậu cảm thấy thích thú. Đây là lý do để cuốn sách này
bắt đầu. Tôi hy vọng bạn - người đọc thân mến - sẽ tìm
thấy vấn đề của riêng mình, rồi có thể giải quyết được
bằng lập trình. Và tôi hy vọng cuốn sách này sẽ giúp ích
cho bạn.
Tôi có một vài lời khuyên.
Đừng vội vàng. Tôi hiểu mong muốn của bạn là đi
thẳng đến chương cuối cùng, tải code của chương trình
- phiên bản cuối cùng xuống và chạy nó. Đừng làm điều
đó. Hãy đi từng bước một, hãy tự viết code (vui lòng
không copy và paste!), cứ thử đi thử lại. Đôi khi bạn sẽ
phải quay đọc lại chương trước. Đôi khi bạn sẽ cần nghỉ
ngơi.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Đừng lo lắng, hãy nghỉ ngơi, hãy làm lại chương này. Chỉ
cần đừng bỏ cuộc.
Mắc sai lầm. Bạn không học được gì khi mọi thứ diễn
ra hoàn hảo. Chỉ có cách để học là phạm sai lầm. Đừng
sợ sai lầm. Hãy thử nghiệm code, hãy thay đổi mọi thứ,
cứ nhận thông báo lỗi và đọc chúng. Hãy tìm kiếm thông
báo lỗi trên Internet và khám phá hàng nghìn người
khác cũng mắc lỗi tương tự. Hãy tìm hiểu cách họ sửa
lỗi như thế nào và tự sửa cho chính mình. Hãy tiến về
phía trước và đừng bỏ cuộc.
Hỏi các câu hỏi. Hãy hỏi bạn bè, hỏi ông bà cha mẹ, hỏi
Internet. Hãy giải thích vấn đề của bạn cho ai đó – đôi
khi như vậy là đủ để tự bạn tìm ra câu trả lời. Không có
cái thứ gọi là “câu hỏi ngu ngốc”, bạn đừng ngại. Hãy đặt
câu hỏi và đừng bỏ cuộc.
Đi xa hơn. Sửa đổi ứng dụng bạn tạo ra bằng cuốn sách
này. Hãy thay đổi điều gì đó để làm cho nó trông giống
ứng dụng của riêng bạn hơn. Hãy suy nghĩ về các ứng
dụng khác mà bạn có thể làm được. Hãy quan sát xung
quanh bạn: những gì có thể được tự động hóa đây? Bạn
có thể tạo một ứng dụng tương tự như ứng dụng hoặc
trang web mà bạn đã biết không? Hãy nói với bạn bè về
ý tưởng của bạn – có thể các bạn sẽ cùng nhau tạo ra thứ
gì đó? Lập trình thực là vui, đừng bỏ cuộc.
Nói ra. Vui lòng cho tôi biết suy nghĩ của bạn trong
liveBook Discussion forum về những gì đã được viết cho
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đến nay và những gì bạn muốn thấy trong phần còn lại
của cuốn sách. Phản hồi của bạn sẽ là vô giá trong việc
cải thiện Let's Talk Python

—Pavel Anni

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Mục lục

1 Cà phê cho bạn bè: Bước đi đầu tiên


2 Danh sách: Có gì trên menu?
3 Hàm: Đừng lặp lại chính mình!
4 Lỗi người dùng: Ai cũng có thể mắc lỗi
5 Thao tác với tệp: Trong vai trò quản lý cửa hàng
6 Menu chính: Khách hàng tiếp theo!
7 Tạo hàm: Nhận đơn hàng và in đơn hàng
8 Thao tác với JSON: Lưu đơn hàng
9 Hoàn thành menu: Một chương trình thực tế
10 Học Flask: Ứng dụng web đầu tiên của bạn
11 Mẫu web đặt hàng: Quán cà phê trên web
12 Kiểu dáng: Làm cho nó đẹp hơn
13 Các bước tiếp theo: kế hoạch cho tương lai

PHỤ LỤC
A Ý tưởng cho ứng dụng đầu tiên của bạn
B Cách cài đặt Mu Editor và môi trường Python

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Cà phê cho bạn bè: Bước đi đầu tiên


1
Chương này bao gồm
 Erik nảy ra một ý tưởng
 Erik và Simon thảo luận về ứng dụng trong
tương lai
 Erik cài đặt trình editor viết code và thử chạy
chương trình đầu tiên bằng Python
 Simon giải thích cách sử dụng các biến
 Erik viết câu lệnh đầu tiên bằng Python

1.1 Một ý tưởng tuyệt vời

Tất cả bắt đầu vào một ngày hè đầy nắng. Erik về nhà
với một ý tưởng: cậu muốn chuẩn bị cà phê và đồ uống
cho bạn bè. Liệu có ai biết rằng cậu ta muốn tạo ứng
dụng trực tuyến cá nhân không nhỉ?
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Mình sẽ làm ra chương trình giống như ở Starbucks,


với nhiều loại hương vị flavors và các lớp toppings,” cậu
nghĩ bụng. “Dường như hiện tại mình có mọi thứ cần
thiết: cà phê, ba hoặc bốn hương vị flavor để trộn, kèm
thêm một ít kem sô cô la phủ topping. Thật tuyệt vời!"
"iPad của em đâu rồi?" Cậu hỏi anh trai Simon.
"Em vất nó linh tinh chỗ nào. Giờ em cần hả?"
"Em cần nó để thu thập đơn đặt hàng cho quán cà phê
cá nhân!"
Cậu ta trở lại sau vài phút với ghi chú trên iPad, nhìn
quanh tìm bốn ly cho mấy người bạn, rồi lại bỏ đi một
lần nữa.
"Đó không phải là một ý kiến hay sao anh?" Cậu hỏi
Simon khi quay lại cầm theo bốn chiếc cốc nhựa rỗng.
"Phải rồi, một ý tưởng tuyệt vời," Simon nói. "Nhưng
mà…"
"Nhưng gì ạ??" Erik hỏi. Cậu cảm thấy rằng anh trai
mình muốn làm hỏng ngày hôm nay vậy, anh ấy vẫn
thường hay làm thế.
“Em viết đơn đặt hàng vào iPad, như thể dùng một cuốn
sổ ghi chú thông thường. Em hãy tạo một ứng dụng đơn
giản cho quán cà phê cá nhân, hãy để chương trình nhận
đơn đặt hàng đi."
"Ý anh là - giống hệt một cửa hàng trực tuyến đúng
không ạ? Có thực đơn và tất cả những thứ khác à?" Erik

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

tưởng tượng tới cửa hàng trực tuyến cá nhân với tấm
biển lớn ở trên đề: "Quán cà phê Erik."
"Đúng rồi, tất nhiên là thế. Em đã biết một chút về
Python từ khóa học trực tuyến trước đây, đúng chưa?"
"Vâng, nhưng em không nhớ nhiều lắm. Bọn em có làm
một ít bài tập... Em nghĩ sẽ xương xẩu đây – phải làm nó
hệt như một cửa hàng trực tuyến thực sự."
“Đừng lo,” Simon nói. "Chúng ta sẽ làm từng bước một.
Anh đã thực hiện một số dự án như thế này cho đội
robot ở trường."
LƯU Ý: Đừng lo lắng nếu trước đây bạn chưa có kinh
nghiệm lập trình gì. Bạn Erik cũng chả nhớ được
mấy từ chương trình từng học, nào chúng ta bắt đầu
thôi.
Simon đang học năm cuối trung học. Anh đã học Python
vài năm trước và sử dụng kiến thức này trong câu lạc
bộ Khoa học Máy tính của trường và gần đây là trong
đội Người máy.
"Thế có nghĩa là, anh đang nói là chúng ta có thể xây
dựng một ứng dụng trực tuyến thực sự phải không?"
Erik vẫn chưa bị thuyết phục hoàn toàn.
"Phải, chắc chắn thế rồi. Nếu em không bỏ ngang lớp
học của anh," Simon mỉm cười nói, "Em sẽ xây dựng nó
trong một vài tuần. Sau đó, khách hàng của em sẽ được
chọn bất kỳ đồ uống nào họ muốn, trộn thêm hương
vị…”
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Và toppings nữa!" Erik chen ngang.


"Đúng, và toppings. Rồi khi họ xác nhận đơn đặt hàng
xong, em sẽ thấy nó trên trang đơn đặt hàng. Sau đó em
sẽ biết phải chuẩn bị những gì và để cho ai. Nó tựa tựa
như thế này," và Simon lấy một mảnh giấy và bắt đầu vẽ
một trang web đơn giản.
"Đây sẽ là trang đặt hàng của em."

"Và đây sẽ là danh sách các đơn đặt hàng của em."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tuyệt vời! Anh có nghĩ chúng ta làm được không??"


Erik vẫn không thể tin nổi anh trai mình.
"Tất nhiên! Như anh đã nói: chỉ cần đừng bỏ ngang. Em
có nhiều thời gian để hoàn thành nó trong quãng
nghỉ hè."
LƯU Ý: Chúng ta có một số ý tưởng dự án khác mà
bạn có thể sử dụng nếu không thích ý tưởng quán
cà phê. Một số trong số chúng sẽ được thảo luận khi
bạn bè của Erik tham gia cùng bạn ấy trong các
chương sau. Xem thêm chi tiết trong Phụ lục A

1.2 Việc đầu tiên: cài đặt

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Hãy bắt đầu với một số điều đơn giản. Chả mấy mà em
sẽ nhớ Python thôi. Em đã cài đặt nó trên máy tính xách
tay cá nhân chưa?" Simon hỏi.
"Chưa, em chưa từng nghĩ tới việc này."
"Đây là một trình soạn thảo editor Python tuyệt vời,
được thiết kế dành riêng cho những người mới bắt đầu
như em. Nó có tên là Mu Editor. Hãy thử tìm nó và cài
đặt đi. Em sẽ làm được, anh tin điều ấy."
Erik đã tìm thấy trang web: https://codewith.mu/ để tải
phần mềm

Cậu ấy download chương trình cài đặt từ trang


này: https://codewith.mu/en/download.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik click vào Instructions - Hướng dẫn và chuyển sang


một trang hướng dẫn với tất cả các bước dành cho máy
tính (lúc đó cậu ấy đang sử dụng Macbook, trang web
có sẵn hướng dẫn cho cả ba hệ điều hành: Windows,
macOS và Linux.)
Bạn có thể tìm thấy tất cả các liên kết và hướng dẫn cần
thiết trong Phụ lục B.
"Đừng lo, nó không phải đồ chơi đâu. Đấy là một công
cụ editor hoàn hảo," Simon nói. "Bọn anh sử dụng nó
cho người máy của nhóm để làm việc với vi điều khiển.
Như em thấy đó, có các phiên bản dành cho Windows,
macOS và Linux. Anh sử dụng phiên bản Linux cho
nhóm."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Liệu còn trình soạn thảo nào khác cho Python không
ạ?" Erik không muốn chỉ làm theo hướng dẫn của ông
anh trai.
"Có, tất nhiên là nhiều lắm. Một lựa chọn tốt khác cho
người mới bắt đầu là Thonny. Hãy xem tại đây:
https://thonny.org/ "

"Nhìn trông hay hay!" Erik mỉm cười. "Cái tên khá là
buồn cười."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tất nhiên còn có những trình soạn thảo code khác hoạt
động trên mọi nền tảng:
- Code VS (htpps://code.visualstudio.com),
- Sulime Text ( http://www.sublimete).
"Tất cả chúng đều hoạt động hoàn hảo với Python.
Ngay cả những trình soạn thảo rất cũ như Vim
(https://www.vim.org/) và Emacs
(https://www.gnu.org/software/emacs/) cũng hỗ trợ
Python, nhưng em phải là một lập trình viên rất
chuyên nghiệp mới sử dụng được chúng," Simon nháy
mắt với em trai mình. "Mu Editor và Thonny," Simon
tiếp tục, "Cả hai đều đã có sẵn Python khi cài đặt. Để sử
dụng Python với các trình soạn thảo khác, em phải cài
đặt nó trước. Trên một số Hệ điều hành như Linux và
macOS, Python đã có sẵn trước rồi. Với Windows, em
nên cài đặt nó. Anh có thể chỉ cho em sau nếu em
muốn."
LƯỢT CỦA BẠN : Hãy cài đặt môi trường Python
Bây giờ đến lượt bạn. Mở máy tính xách tay hoặc
máy tính để bàn ra và cài đặt Mu Editor. Bạn có thể
tìm hướng dẫn đầy đủ cho các nền tảng hệ điều
hành khác nhau trong Phụ lục B (nó khả dụng trên
Windows, macOS, Linux).
Nếu bạn thích một số trình editor khác, cứ thoải mái
cài đặt nó thay cho Mu. Đừng ngại thử nghiệm!

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

1.3 Cách nói chuyện với máy tính

"Hãy bắt đầu Mu Editor và thử viết chương trình quán


cà phê của em luôn đi" Simon nói.
Erik đã khởi chạy Mu và nhìn thấy cửa sổ đầu tiên:

"Chọn Python 3 trên menu và bấm OK," Simon gợi ý.


Erik làm theo lời Simon. "Từ giờ trở đi," Simon tiếp tục,
"Mu Editor sẽ nhớ rằng em luôn sử dụng Python 3. Em
có thể nhận thấy rằng có một số chế độ khác được sử
dụng để làm việc với các bộ vi điều khiển, xây dựng các
ứng dụng web và các ứng dụng khác. Chúng ta sẽ tìm
hiểu về chúng sau."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Bây giờ Erik đã có cửa sổ soạn thảo trước mặt

"Em nên viết gì đây?" Erik hỏi.


"Em muốn chương trình của mình làm gì đầu tiên?"
"Nó cần nói là 'Chào mừng đến với Tiệm cà phê của
Erik!'"
"Được! Hãy viết nó đi. Em có nhớ hàm print() trong
Python không?"
Erik bắt đầu viết. Bước đầu tiên này thật dễ dàng.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Giờ thì sao ạ?"

"Bây giờ em chạy nó. Kích Click Run Chạy."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik bấm nút, rồi đột nhiên một cửa sổ khác nhảy ra hỏi
cậu có muốn lưu chương trình không. Điều này thật dễ
dàng. Erik gõ tên file: "coffeeshop" và sẵn sàng nhấn
ENTER để lưu tệp bỗng Simon hô:
"Đợi đã, đợi đã... Đừng quên thêm đuôi .py vào tên file.
Em phải cho trình soạn thảo editor biết rằng đó là một
chương trình Python. Trình soạn thảo Mu sẽ tự động
thêm đuôi của tệp, nhưng các trình soạn thảo khác thì
không. Vì vậy, hãy đảm bảo tất cả các tệp Python của em
được đặt thêm đuôi .py."
Erik viết thêm .py vào tên file và save lại. Ngay sau đó,
cậu nhận thấy có một cửa sổ khác ở cuối cửa sổ của
trình soạn thảo. Chính là là lời chào của quán cà phê –
đúng hệt như cậu muốn!

"Nó hoạt động rồi !" Erik mừng rỡ.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tất nhiên là nó hoạt động. Tại sao em nghĩ nó không


hoạt động?" Simon nói. "Có phải em muốn thu thập đơn
đặt hàng không?”
"Vâng, em sẽ hỏi tên khách hàng và họ muốn gì..."
“Rồi sau đó thì sao?…” Rõ ràng Simon biết câu trả lời,
nhưng anh muốn Erik tự tìm ra.
"Rồi sau đó em muốn in dòng chữ 'Xin chào! Đây là đơn
đặt hàng của bạn:' Tiếp nữa là hiển thị tên, hương vị
flavor và topping khách hàng chọn. Nó phải y hệt như
một đơn đặt hàng thực sự."
“Ý kiến hay đấy,” Simon nói. "Nhưng hãy nhìn này: khi
em đang viết chương trình, em sẽ không biết khách
hàng muốn đặt hàng cái gì, phải không nào? Vì vậy, em
không thể viết vào chương trình của mình 'Bạn đã gọi
món caramen.' Thêm nữa, các khách hàng khác nhau sẽ
đặt hàng những món khác nhau. Có thể là caramel cho
Alex hay dâu tây cho Emily. Do đó em sẽ thấy rằng:
flavor hương vị thay đổi – varies trong từng đơn đặt
hàng, cả tên của khách hàng mỗi đơn một khác. Có nhớ
thứ này được gọi là gì trong lập trình không?"
"Đó là biến – variable!" Erik mừng là mình vẫn còn nhớ
ra nó từ môn Python đã học vài tháng trước .
"Đúng rồi!" Simon cũng thấy vui." Biến giống như một
chiếc hộp: em đặt một thứ vào đó, rồi sau đó mở ra xem
có gì có trong hộp. Em có thể thay thế thứ trong hộp
bằng một thứ khác."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Trong trường hợp của chúng ta," Simon tiếp tục, "Hãy
bắt đầu với một hộp tên là ‘answer’ - answer và lưu trữ
bất cứ thứ gì em nghe từ khách hàng vào trong hộp đó.
Ví dụ em hỏi tên của khách hàng và họ trả lời 'Alex'. Em
đặt câu trả lời này vào hộp có tên ‘answer’ và giữ nó tại
đây. Khi nào khách hàng muốn in ra, em nói với Python:
'vui lòng in bất cứ thứ gì hiện có trong hộp có tên
‘answer’. Tên khách hàng tiếp theo là Emily, bây giờ thì
em điền 'Emily' vào ô. Và lần tới, Python sẽ in ‘Emily'
không phải 'Alex' bởi vì đó là nội dung trong ô ‘answer’.
Bây giờ hãy viết code vào đây."
"Làm luôn ở đây, trong cùng một tệp này ạ?" Erik hỏi.
"Chắc chắn rồi, hãy tiếp tục trong cùng một tệp. Để lấy
nội dung nào đó từ khách hàng, ta sử dụng hàm có tên
là input(). Khi em gọi hàm này, nó sẽ đợi người dùng
nhập nội dung vào. Người dùng nhập nội dung trên bàn
phím và nhấn ENTER. Sau đó hàm trả về - returns nội
dung là những gì người dùng đã nhập”.
“Đợi đã,” Erik ngăn Simon lại. "Trả về có nghĩa là gì? Mà
này, anh đang nói về hàm. Tất nhiên, em biết chúng là
gì, nhưng anh nói cho em biết 'hàm' có ý nghĩa là gì đi?"
Erik không muốn thể hiện rằng cậu hầu như chẳng còn
nhớ gì về các hàm từ khóa học cũ trước đó.
"Hàm là một đoạn code để làm một việc gì đó. Hầu như
bất kỳ đoạn mã nào cũng để làm một việc gì đó, nhưng
một số đoạn mã chúng ta sử dụng nhiều lần hơn những
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đoạn mã code khác. Tiếp đây, em sẽ tạo ra các hàm của


riêng mình, nhưng bây giờ, chúng ta sẽ sử dụng hàm
được viết bởi người khác, có một số hành động mà mọi
người sử dụng rất thường xuyên, chẳng hạn như in ra
một cái gì đó. Em chưa hiểu hàm, nhưng em đã sử dụng
một hàm khi em gõ print() vữa nãy đấy. Trong lập trình,
chúng ta nói là em đã gọi một hàm."
“A-ha, em hiểu rồi,” Erik nói. "Thứ có dấu ngoặc đơn
được gọi là 'hàm'."
"Phải. Còn em có thể đặt một cái gì đó bên trong những
dấu ngoặc đơn đó, và hàm sẽ làm điều gì đó với nó. Ví
dụ, nó sẽ in mẩu thông tin của em. Những gì em truyền
vào một hàm được gọi là đối số - arguments. Đôi khi đó
là một chuỗi, đôi khi là một con số, đôi khi có tới vài loại
đối số”
"Chúng ta gọi nó là 'truyền các đối số' tới một hàm,"
Simon tiếp tục. "Hàm sẽ thực hiện điều gì đó với các đối
số và nhận cái gì đó làm kết quả - result. Ví dụ: nó có thể
tính toán hoặc thực hiện điều gì đó với chuỗi mà em đã
truyền, chẳng hạn như chuyển đổi chuỗi thành dạng
ALL CAPS (chuyển hết ký tự thành dạng viết hoa) hoặc
mã hóa nó. Và sau đó, hàm trả kết quả đó cho chương
trình chính."
"Nhưng làm thế nào để em có thể nhìn thấy kết quả?"
Erik hỏi. "Hàm sẽ in nó đúng không ạ?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Không, nó sẽ không làm vậy. Đây là chỗ mà chúng ta


cần các biến. Chúng ta sẽ nói với Python: 'vui lòng gọi
hàm này với các đối số này và hãy đặt bất kỳ thứ gì nó
trả về vào hộp này, à là biến này'. Và tất cả điều đó
được thực hiện bằng cách sử dụng một dấu 'bằng' đơn
giản, như thế này = . Ví dụ, nếu em muốn gọi hàm
input() và đặt những gì nó trả về cho biến answer, em chỉ
cần viết đơn giản là:”
answer = input()
"Và sau khi em lưu câu trả lời của khách hàng, em có thể
in nó ra. Em gọi hàm print() và truyền vào biến của em
một đối số."
“Tuyệt quá,” Erik nói, “Giờ thì em đã biết viết nó như thế
nào rồi.” Cậu bắt đầu viết trong trình biên tập - editor.
Sau một phút hoặc hai phút, xuất hiện đoạn mã như
hình sau:
print(“Welcome to Erik’s Coffee Shop!”)
answer = input()
print(answer)
"Em chạy nó nhé?" Cậu hỏi Simon.

"Được chứ, làm đi em, kích [Run] Chương trình


sẽ chạy."

Erik kích [Run] và chương trình Chạy.


"Chương trình hiện 'Chào mừng đến với quán cà phê
của Erik' và sau đó không có gì cả."
"Em đang mong đợi cái gì?" Simon hỏi.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Em mong nó sẽ hỏi tên của em."


"Nhưng em có gõ vào Python rằng nó sẽ hỏi điều gì đó
đâu. Bây giờ nó đang đợi thông tin đầu vào của em đấy.
Gõ mấy chữ vào đi."
Erik gõ: "Erik" và nhấn ENTER
Python in ra: "Erik".

"Nó hoạt động rồi!” Erik hô lên.


LƯỢT CỦA BẠN: Viết đoạn code đầu tiên
Hãy viết đoạn code mà Erik vừa viết. Đó là một
chương trình ngắn, chúng tôi khuyên bạn nên tự
đánh máy thay vì copy từ sách. Hãy nghĩ ra tên cho
quán cà phê riêng bạn và dùng tên đó làm thông
điệp "Chào mừng" đầu tiên. Bạn có thể tạo cửa hàng
khác nếu bạn muốn. Nó sẽ bán cái gì? Quán Kem?

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Cửa hàng hoa? Cửa hàng thú cưng? Hay cửa hàng đồ
chơi?
Thử chạy chương trình của bạn xem. Liệu nó có
làm giống bạn mong đợi không? Nếu chương trình
chạy chưa mượt, hãy copy nó từ trong sách hoặc
từ trang web của chúng tôi:
https://github.com/pavelanni/lets-talk-python-book và
chạy lại. Đó chính là việc bạn nên làm.
"Tuyệt vời, nó đã hoạt động rồi" Simon nói, "Nhưng hãy
làm cho chương trình thân thiện với người dùng hơn.
Có phải là em cảm thấy bối rối khi máy không nói gì mà
chỉ hiện mỗi câu 'Chào mừng' đúng không? Em nên nói
cho người dùng biết em mong đợi từ họ cái gì. Thêm
nữa, thay vì chỉ in 'Erik', em có thể thêm một cái gì đó
kiểu như 'Đây là đặt hàng của bạn, Erik'."
"Em có thể truyền chuỗi này tới hàm input() làm đối số.
Chúng ta gọi nó là chuỗi khai báo. Nó giải thích những
gì chúng ta mong đợi từ người dùng. Và trong hàm
print(), em có thể thêm chuỗi em muốn in trước biến
answer. Để anh gõ cho."
Simon đã giúp Erik thêm các chuỗi đó vào code và đây
là màn hình sau đó:
print(“Welcome to Erik’s Shop!”)
answer = input(“Please enter your name: ”)
print(“Here is your order, “, answer)

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon để ý thấy Erik đang tìm nút [Run] bèn giải

thích: "Trước khi ấn [Run] để chạy lại chương


trình, em phải dừng hoạt động phiên Python chạy trước
đó. Em có thấy ba cái dấu ngoặc nhọn ở đây không?
Chúng có nghĩa là Python đang chạy và đang chờ đầu
vào của em. Chúng ta sẽ dùng nó sau, còn bây giờ, chỉ

cần kích [Stop] để cắt ngang chương trình rồi kích

[Run] để chạy lại."


Bây giờ chương trình đã làm chính xác như Erik đã lập
trình.
Welcome to Erik’s Shop!
Please enter your name: Erik
Here is your order, Erik
>>>
LƯỢT CỦA BẠN : Làm cho chương trình của bạn
thân thiện hơn với người dùng
Thêm phần khai báo và chuỗi đầu ra cho chương
trình đầu tiên. Tạo một lời nhắc khác hỏi tên khách
hàng, chẳng hạn như "Rất vui được gặp bạn! Tên
bạn là gì?"
"Có vẻ đã thân thiện với người dùng hơn rồi, phải không
em?" Simon hỏi. " Hãy luôn nghĩ về người dùng và luôn
tự hỏi: Những gì họ thấy đã đủ rõ ràng chưa? Họ có thể
phạm sai lầm ở đâu không ?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Bây giờ," Simon tiếp tục, "Chúng ta phải hỏi khách hàng
của em về đơn đặt hàng của họ. Em nói em có cà phê và
sô cô la. Còn em cũng đã nói điều gì đó về hương vị
flavor và lớp topping phải không?"
“Vâng,” Erik nói, “Em muốn hỏi họ muốn loại topping và
hương vị nào.”
"Chà, hãy tiếp tục và hỏi họ. Em chỉ cần lặp lại cùng một
code - nhưng đừng quên thay đổi câu nhắc nhở. Và anh
nghĩ em nên in toàn bộ thứ tự ở cuối chứ không phải
sau mỗi câu hỏi. Hãy làm đi nào."
Erik đã viết code này và dừng lại ở dòng cuối cùng.
print(“Welcome to Erik’s Shop!”)
answer = input(“Please enter your name: ”)
answer = input(“Please enter your drink: ”)
answer = input(“Please enter your flavor: ”)
answer = input(“Please enter your topping: ”)
print(“Here is your order: “, answer)
"Anh bảo em đặt câu trả lời vào biến answer. Nhưng làm
sao em biết bây giờ đâu là câu trả lời cho hương vị flavor
đâu là câu trả lời cho topping?" Erik bối rối.
"Đúng anh đã bảo em đặt câu trả lời vào biến, ví dụ gọi
là 'answer'," Simon đáp. Ở đây chúng ta đến với một
trong những vấn đề khó khăn nhất trong khoa học máy
tính: đặt tên cho các biến", Anh mỉm cười. "Tất nhiên,
em không lưu trữ tất cả các câu trả lời trong biến được
gọi là answer được. Hãy sử dụng các biến khác nhau cho
các câu trả lời khác nhau và đặt cho chúng những cái tên
có ý nghĩa. Đối với tên của khách hàng, chúng ta sẽ sử

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

dụng một biến gọi là name – đặt tên dễ dàng lắm. Nếu em
hỏi về đồ uống chính, hãy đặt câu trả lời trong biến là
drink hoặc product. Đối với các câu trả lời về hương vị
flavor và topping, hãy sử dụng các biến flavor và
topping."
"Cuối cùng," Simon tiếp tục nói, "In mỗi biến trên một
dòng riêng biệt, sử dụng vài hàm print(). Cố lên nào. Anh
sẽ giúp em nếu cần thiết."
Erik gõ một loạt code và cuối cùng tạo ra như hình bên
dưới:
Listing 1.1 coffeeshop.py
print(“Welcome to Erik’s Shop!”)
name = input(“Please enter your name: ”)
drink = input(“Please enter your drink: ”)
flavor = input(“Please enter your flavor: ”)
topping = input(“Please enter your topping: ”)
print(“Here is your order: “, name)
print(“Main product: “, drink)
print(“Flavor: “, flavor)
print(“Topping: “, topping)
print(“Thanks for your order! “)
Erik kích Click Run và chương trình của anh ấy bắt đầu
chạy. Erik đã trả lời tất cả các câu hỏi và nhận được một
kết quả tốt đẹp:
Welcome to Erik’s Shop!
Please enter your name: Erik
Please enter your drink: coffee
Please enter your flavore: caramel
Please enter your topping: chocolate
Here is your order, Erik
Main product: coffee
Flavor: caramel
Topping: chocolate
Thank for your order!
>>>

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon chú ý đến dòng cuối cùng và khen ngợi sáng kiến
của Erik: "Thật tuyệt vời khi cảm ơn khách hàng."
“Đúng rồi, em đã thấy điều đó trên một số hóa đơn ở
quán cà phê,” Erik đáp. Cậu ta đang vui vì cậu đã làm
một cái gì đó của riêng mình ngoài những gì anh trai đã
chỉ cho.
LƯỢT CỦA BẠN Thêm nhiều lựa chọn hơn cho file.
Hãy sử dụng các biến.
Chỉnh sửa chương trình trước đó của bạn và thêm
các dòng khác vào chương trình. Một lần nữa, vui
lòng thay đổi lời nhắc và chuỗi bạn in thành thứ gì
đó phù hợp hơn với dự án cá nhân.
Thay hiển thị in ra ở đầu ra. Hãy xem đơn đặt hàng
từ những nơi bạn từng ghé thăm (quán cà phê, nhà
hàng, cửa hàng tạp hóa, cửa hàng khác). Cố gắng làm
cho hiển thị in ra ở đầu ra của bạn trông tương tự.
Sử dụng thêm các ký hiệu như |, _, =, +, và các ký hiệu
khác ở đầu ra để trông thêm thú vị.
Simon quyết định đã đến lúc kết thúc ngày hôm nay.
"Anh nghĩ rằng đó là một khởi đầu tốt cho ngày hôm
nay," Anh nói. "Hãy xem những gì chúng ta đã làm ngày
hôm nay đi. Đầu tiên, chúng ta đã cài đặt môi trường lập
trình."
“Vâng,” Erik nói. "Em thích chương trình Mu Editor này.
Nó sử dụng màu sắc để hiển thị cho các phần khác nhau
của chương trình. Và nó cũng hiển thị chuỗi của em màu
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đỏ cho đến khi em đặt dấu ngoặc kép ở cuối. Và nó có


một chế độ tối – dark mode! Em biết rằng các lập trình
viên thực thụ luôn sử dụng chế độ tối màu! Em nghĩ
rằng em sẽ tiếp tục sử dụng nó."
"Thứ hai là" Simon nói, "Lần đầu tiên chúng ta sử dụng
một hàm. Đó là gì?"
"Đó là hàm print() ạ," Erik nói. "Em bảo máy in cái gì thì
nó in cái đó”
"Phải. Em đã gọi được hàm, đã truyền được đối số
argument cho nó."
"Thứ ba là," Simon tiếp tục, "Em đã sử dụng một hàm
khác để lấy thông tin từ người dùng."
"Đó là input() ạ ," Erik nói. "Và em đã lưu các câu trả lời
vào trong các biến"
"Tuyệt vời !" Simon thực sự tự hào về em trai mình. "Em
đang có tiến bộ tốt."
LƯỢT CỦA BẠN Hãy tự giải thích
Thử giải thích các khái niệm bằng ý của cá nhân bạn.
• Hàm là gì? Đưa ra vài ví dụ.
• Đối số của hàm là gì? Đưa ra vài ví dụ.
• Cách gọi một hàm ?
• Biến là gì? Tại sao chúng ta cần chúng?
• Chúng ta nên đặt tên biến như thế nào? Tại sao?

1.4 Chương trình là gì?

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Cuối cùng, hãy bổ sung thêm một chút lý thuyết nào”


Simon nói. "Chúng ta đang xây dựng một chương trình
rất đơn giản. Nhưng nó có tất cả các thành phần chính
như bất kỳ chương trình nào khác. Chúng ta đã yêu cầu
người dùng cung cấp một số thông tin đầu vào. Sau khi
nhận được dữ liệu từ người dùng, chúng ta đã làm một
số việc với dữ liệu đó. Ta gọi đó là quá trình xử lý thông
tin. Trong trường hợp của chúng ta, chúng ta chỉ lưu trữ
dữ liệu, nhưng chúng ta có thể làm gì đó nữa với nó,
đúng không nào?"
"Ví dụ là gì ạ?" Erik hỏi.
"Ví dụ: em đã nhập 'cà phê' bằng chữ thường, nhưng
chúng ta có thể muốn bắt đầu tất cả các sản phẩm và
hương vị bằng chữ in hoa đầu tiên. Có một chức năng
đặc biệt trong Python làm điều đó. Tức là, chúng ta có
thể xử lý dữ liệu sau khi đã nhận được."
"Ý tưởng tuyệt vời, em muốn thực hiện đây!" Erik nói.
"Chắc chắn rồi, chúng ta sẽ làm. Và cuối cùng, sau khi xử
lý dữ liệu, chúng ta in nó ra. Nói cách khác, chúng ta đã
tạo ra một số đầu ra. Em nhìn đây này."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đầu vào không phải lúc nào cũng đến từ người dùng,"
Simon tiếp tục giảng giải. "Đôi khi không phải là tương
tác với người dùng mà chương trình lấy dữ liệu từ một
nơi khác. Ví dụ, lấy từ Internet, như kết quả thể thao
chẳng hạn. Đôi khi từ các cảm biến, như trong robot,
hoặc từ các tài liệu và hình ảnh."
"Thông thường, đầu ra không chỉ là thông tin in ra.
Trong nhóm người máy của anh, bọn anh nhận thông
tin đầu vào từ các cảm biến, rồi xử lý chúng trong bộ vi
điều khiển và đầu ra của chúng là các tín hiệu tới các
động cơ như: 'rẽ trái, tiến về phía trước.' Nhưng cấu trúc
thì giống nhau cả: đầu vào → xửlý → đa• u ra."
“Lý thuyết thế đủ rồi,” Simon nói. "Ngày mai chúng ta sẽ
làm việc để cải thiện chương trình của em."
"Nâng cấp ạ?" Erik ngạc nhiên. "Nhưng nó hoạt động tốt
rồi, đúng thế mà?"
"Điều gì sẽ xảy ra nếu người dùng của em nhập thứ gì
đó mà em không có trong cửa hàng của mình?" Simon
hỏi. "Giống như là 'xi-rô cây phong'? Em sẽ làm gì? Em
nên nói với người dùng những gì em có trong quán cà
phê và những gì họ có thể đặt hàng. Vì vậy, ngày mai
chúng ta sẽ làm việc trên menu. Ngoài ra, chúng ta sẽ
xem có việc gì cần làm trong trường hợp menu lỗi."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

1.5 Các thuật ngữ mới hôm nay chúng ta


học

● Biến
Một nơi (hộp), nơi chúng ta có thể lưu trữ một số giá trị.
Ví dụ, chúng ta có thể lưu trữ định dạng số, ký tự, chuỗi.
Một biến chỉ có thể chứa một thứ ở tại một thời điểm.
● Hàm
Một đoạn code thực hiện điều gì đó và chúng ta muốn
làm đi làm lại điều đó.
● Đối số của hàm
Thông tin mà hàm cần để thực hiện công việc.
● Để gọi một hàm
Hãy viết tên của hàm với dấu ngoặc đơn và đối số giữa
dấu ngoặc

1.6 Code cho chương này

Bạn có thể tìm thấy code cho chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch01

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Danh sách: Có gì trong menu?

Chương này bao gồm


● Erik bắt đầu tạo menu cho quán cà phê
2
● Erik dùng list (danh sách) trong Python cho
drinks, flavors và toppings
● Erik sử dụng vòng lặp để in danh sách
● Simon giải thích cách máy tính lưu trữ định dạng
số và định dạng chuỗi
● Erik học được một điều quan trọng về chỉ mục-
index của list (danh sách)
Ngày hôm sau, Erik đã sẵn sàng để tiếp tục làm việc với
ứng dụng Quán cà phê. Cậu nhớ rằng Simon đã nói điều
gì đó về những sản phẩm không có mà khách hàng có
thể sẽ đưa ra yêu cầu. Cậu đến chỗ anh trai và hỏi:
"Hôm qua anh đã nói rằng khách hàng có thể nhập thứ
gì đó mà em không có trong cửa hàng. Em nên làm gì
bây giờ?"
"Hãy nhớ lại lần cuối cùng em vào quán cà phê hoặc nhà
hàng. Em biết em cần đặt đồ như thế nào không?”
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Họ có một thực đơn với danh sách các sản phẩm mà họ
có."
"Đúng!" Simon nói. "Một menu! Đây là những gì chúng
ta sẽ tạo hôm nay. Menu sẽ trông như thế nào cho một
quán cà phê?"
"Đó là một danh sách. Một danh sách các đồ uống chính
như cà phê, sô cô la, decaf (đồ uống khử caffein). Và một
danh sách các hương vị flavor ta có thể thêm vào. Như
là caramel, bạc hà, và những thứ khác. Và một danh sách
toppings."
"Đúng, danh sách!" Simon rất vui vì Erik đã dùng đúng
từ. "Như thế này phải không?" Rồi chả mấy chốc anh ấy
đã soạn thảo một cái gì đó trông giống một thực đơn.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chúng ta cần các danh sách - List! Chúng ta có danh


sách trong Python - em nhớ điều đó nhé. Danh sách rất
hữu ích trong Python. Chúng có thể chứa định dạng số,
định dạng chuỗi, thậm chí là cả danh sách nữa. Ví dụ,"
Simon đã lấy một mảnh giấy và viết một số ví dụ.

Hãy tạo danh sách cho thực đơn của em. Em chỉ cần đặt
tên cho danh sách - chẳng hạn như flavor, và sau đó liệt
kê các loại hương vị của em trong ngoặc vuông. Làm
tương tự cho toppings và đồ uống chính. Đừng quên
rằng flavor, topping, đồ uống của em là chuỗi nên chúng
phải được đặt trong dấu ngoặc vuông. Em có thể bắt đầu
một tệp mới trong trình editor và gọi nó là menu.py
chẳng hạn."
Erik mở trình soạn thảo và bắt đầu gõ. Đây là kết quả
cậu làm trong vài phút.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
“Rất tốt,” Simon nói. "Bây giờ hãy in chúng dưới dạng
menu nào."
"Chỉ là print(drinks) phải không ạ?" Erik hỏi.
"Em làm đi, nhưng nó sẽ không đẹp đâu. Thử biết liền."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik đã thêm câu lệnh print() vào dòng cuối.


drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
print(drinks)

"Kích Run Chạy xem nào" Simon nói.


Erik kích Click và thấy đầu ra ở cuối cửa sổ soạn thảo
[“chocolate”, “coffee”, “decaf”]
>>>
"Nếu thực đơn của em là một danh sách, chúng ta nên
in dưới dạng danh sách," Simon nói. "Và em cũng nên
cung cấp cho người dùng một cách để chọn từ danh
sách. Ví dụ: Em có thể yêu cầu nhập một chữ cái. Nhưng
ở đây chúng ta có sô cô la và cà phê. Vì vậy, em không
thể sử dụng chữ 'C' cho cả hai món. Thay vào đó, ta hãy
sử dụng các con số. Mỗi mục item trong menu chúng ta
sẽ gán cho một con số. Sau đó, người dùng sẽ chọn nhập
một con số. Ví dụ số 1 cho sô cô la, số 2 cho cà phê. Kiểu
kiểu thế này." Simon lấy một mảnh giấy và vẽ một menu
đơn giản.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Vâng, em đã thấy điều đó ở một nhà hàng Trung


Quốc—mỗi món ăn đều được đánh một con số,” Erik
nhớ lại. "Nhưng em làm điều đó với Python như thế
nào?"
"Em có một danh sách gồm nhiều mục - item" Simon bắt
đầu giải thích. "Em phải in từng mục – item chèn thêm
một con số ở phía trước. Khi chúng ta phải lặp lại điều
gì đó trong Python, chúng ta sử dụng vòng lặp. Trong
trường hợp này vòng lặp sẽ là một for-loop (vòng lặp
for). Em nói với Python rằng đối với mỗi mục - item
trong danh sách, nó phải làm một việc gì đó. Chẳng hạn
như in các item ra."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Hãy viết một vòng lặp for đơn giản," Simon nói tiếp.
"Để anh viết vòng lặp đầu tiên cho em." Simon lấy bàn
phím của Erik và thêm một vài dòng vào code của cậu
ấy.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
for d in drinks:
print(d)
Simon kích [Run] và hai anh em nhìn kết quả:
chocolate
coffee
decaf
>>>
"Bây giờ đến lượt em," Simon bảo. "Viết code giống thế
cho hai danh sách còn lại. Lưu ý rằng anh đã sử dụng
một biến khác để in các item trong danh sách.
Danh sách được gọi là đồ uống - drinks. Anh chỉ sử dụng
một chữ d cho mỗi đồ uống trong danh sách. Đây là cái
cách thông thường để đặt tên có liên quan cho biến,
chẳng hạn như drinks cho danh sách đồ uống. Nhưng mà
một biến sẽ chỉ được sử dụng cho một vòng lặp để duyệt
một danh sách, nó nên ngắn thôi, có thể chỉ một hoặc
hai ký tự. Đây không phải là quy tắc, chỉ là gõ nhanh hơn
thôi."
"Một điều quan trọng nữa," Simon tiếp tục, "Trong
Python dấu cách - space có ý nghĩa rất lớn. Em có thấy
lệnh gọi hàm print() bị dịch sang phải bốn dấu cách
không? Đây là cách chúng ta nói với Python cái gì sẽ

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

được lặp lại trong vòng lặp. Phần được dịch chuyển
được gọi là một khối. Mọi thứ em đặt trong khối này sẽ
được lặp lại cho mỗi mục – item trong danh sách. Bây
giờ chỉ gọi có một hàm, nhưng chúng ta sẽ thêm các thứ
đó sau.
"Em chắc cũng thấy rằng anh không gõ bốn dấu cách
trên bàn phím. Trình editor đã tự động làm giúp rồi. Tất
cả các chương trình editor mà em sử dụng cho Python
đều có tính năng này. Khi máy nhìn thấy dấu hai chấm
(:) chúng sẽ tự động dịch khối ở dòng tiếp theo. Nó được
gọi là 'bắt đầu một khối mới’. Bây giờ hãy tiếp tục viết
các vòng lặp."
Erik tạo thêm hai vòng lặp để in hai danh sách còn lại.
Cậu ta thích ý tưởng sử dụng biến ngắn hơn tên (đỡ phải
gõ nhiều!). Cậu cũng nhận thấy rằng trình soạn thảo đã
tự động dịch khối sau dấu hai chấm. Có ích thật!
Đây là đoạn code cậu ta đã có.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
for d in drinks:
print(d)
for f in flavors:
print(f)
for t in toppings:
print(t)
Erik lưu chương trình lại rồi bấm nút Run.
LƯỢT CỦA BẠN: Tạo danh sách sản phẩm rồi in ra.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Mở editor viết code ra và tạo một chương trình


tương tự như những gì Erik vừa làm. Nó nên chứa
ba hoặc nhiều list các item. Sau đó sử dụng các vòng
lặp để in ra nội dung của các danh sách - list.
Bạn có thể sử dụng menu từng item của Erik hoặc
bạn tự tạo item của riêng mình. Kem, hương vị,
bánh mì tròn, các mô hình tí xíu, bất cứ thứ gì bạn
muốn!
chocolate
coffee
decaf
caramel
vanilla
pepermint
raspberry
plain
chocolate
cinnamon
caramel
>>>
“Tốt rồi đấy” Simon nói. "Nhưng chúng ta chưa có con
số. Ta cần sửa thêm tý nữa. Có nhớ là anh đã nói với em
rằng chúng ta có thể thêm cái gì khác vào khối? Đây là
thứ anh đề xuất. Chúng ta sẽ tạo một biến sẽ giữ số thứ
tự của item trong danh sách. Mỗi lần chúng ta chuyển
sang item tiếp theo, ta cộng một vào biến đó. Trong
trường hợp đó, 'sô cô la' sẽ là số một, 'cà phê' - số hai,
v.v."
"Để anh cho em thấy" Thế là Simon lại dùng bàn phím
của Erik.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

i=1
for d in drinks:
print(i, d)
i=i+1
for f in flavors:
print(f)
for t in toppings:
print(t)
Anh chạy chương trình và họ nhìn thấy như hình dưới:
1 chocolate
2 coffee
3 decaf
caramel
vanilla
pepermint
raspberry
plain
chocolate
cinnamon
caramel
>>>
"Em thấy đấy: Anh đã thêm biến i. Bây giờ, đối với mỗi
item trong list, anh không chỉ in giá trị của nó mà còn cả
số của nó ra nữa. Sau đó, anh cộng một vào con số để
chuyển từ 1 sang 2, rồi từ 2 lên 3, v.v. ngay bây giờ hãy
làm đi và sửa phần còn lại," Simon nói.
Erik đã thực hiện các thay đổi:
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
i=1
for d in drinks:
print(i, d)
i=i+1
for f in flavors:
print(i, f)
i=i+1
for t in toppings:
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

print i, (t)
i=i+1
Khi cậu chạy chương trình, đầu ra hiển thị như hình:
1 chocolate
2 coffee
3 decaf
4 caramel
5 vanilla
6 pepermint
7 raspberry
8 plain
9 chocolate
10 cinnamon
11 caramel
>>>
"Đây không phải là điều em muốn!" Erik thốt lên. "Em
nghĩ nó nên là: một, hai, ba cho đồ uống, sau đó trở lại
là một, hai, ba cho phần flavor, rồi một, hai ba cho phần
toppings một lần nữa."
"Đúng rồi!" Simon đồng ý. "Em sẽ làm điều này như thế
nào?"
"Ta sử dụng một biến khác được không ạ?"
"Được, hoàn toàn làm thế được. Nhưng em vẫn có thể
sử dụng cùng một biến i. Điều quan trọng là thiết lập giá
trị nó trước mỗi vòng lặp. Ta gọi đó là xác định giá trị
ban đầu của biến."
Erik đã thêm i = 1 trước mỗi vòng lặp:
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
i=1
for d in drinks:
print(i, d)
i=i+1
i=1
for f in flavors:
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

print(i, f)
i=i+1
i=1
for t in toppings:
print(i, t)
i=i+1
LƯỢT CỦA BẠN: In ba (hoặc nhiều hơn) menu có
đánh số
Sửa đổi chương trình trước đó của bạn để đánh số
cho các mục – item trong menu.
Sử dụng vòng lặp. Đừng quên đặt lại bộ đếm vật
phẩm với mỗi danh sách mới.
Erik bấm Run và nhận được kết quả:
1 chocolate
2 coffee
3 decaf
1 caramel
2 vanilla
3 pepermint
4 raspberry
5 plain
1 chocolate
2 cinnamon
3 caramel
>>>
“Bây giờ chúng ta cùng làm cho nó đẹp hơn một chút
nhé,” Simon nói. "Thêm tiêu đề 'Đồ uống của chúng ta'
trước mỗi danh sách. Em cần nhớ, chúng ta nên cho
người dùng hiểu họ đang thấy gì và họ nên làm gì."
Erik viết thêm các tiêu đề. Thậm chí cậu còn thêm một
dòng phụ nữa dưới mỗi tiêu đề. Cậu chắc chắn rằng bản
thân sẽ làm được một thực đơn trông giống như thực
sự.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

toppings = [“chocolate”, “cinnamon”, “caramel”]


print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
print(“Erik’s Coffee Shop toppings”)
print(“------------------------”)
i=1
for t in toppings:
print(i, t)
i=i+1
LƯỢT CỦA BẠN: Thêm tiêu đề vào menu
Thêm tiêu đề vào menu để làm cho đầu ra đẹp mắt.
Sử dụng tên cửa hàng của bạn trong các tiêu đề. Hãy
thử dùng các ký hiệu khác thay vì dấu gạch ngang.
Thế là, đầu ra đã đẹp đẽ, đúng như cậu mong đợi:
Erik’s Coffee Shop drinks
----------------------
1 chocolate
2 coffee
3 decaf
Erik’s Coffee Shop flavors
-----------------------
1 caramel
2 vanilla
3 pepermint
4 raspberry
5 plain
Erik’s Coffee Shop toppings
------------------------
1 chocolate
2 cinnamon
3 caramel
>>>

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Trông ổn rồi đấy” Simon nói. "Điểm tốt về định dạng


này là bây giờ em có ba danh sách trong menu và ba
danh sách trong chương trình."
"Chúng ta hãy viết code như thế này" Simon nói tiếp.
"Đối với mỗi list trong menu, em phải yêu cầu người
dùng chọn một item, rồi nhận thông tin đó từ họ. Làm
thế nào để em có được thông tin từ người dùng? Anh đã
làm như thế ngày hôm qua, em có nhớ không?"
"Với input() phải không ạ?" Erik hỏi.
"Đúng rồi!" Simon mừng là Erik đã nhớ bài học trước.
"Em có thể tự viết nó, liệu em có làm được không?"
“Để em thử xem,” Erik nói và bắt đầu chỉnh sửa mã code.
Cậu nhớ rằng cần sử dụng hàm input(). Sau đó, cậu đặt
dòng nhắc chú thích bên trong dấu nháy kép và ở phía
bên trái cậu đặt biến. Erik nhớ rằng cậu không nên sử
dụng cùng một biến cho các câu hỏi khác nhau.
Đây là những gì cậu vừa viết xong:
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
drink = input(“Choose your drink: ”)
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

flavor = input(“Choose your flavor: ”)

print(“Erik’s Coffee Shop toppings”)


print(“------------------------”)
i=1
for t in toppings:
print(i, t)
i=i+1
topping = input(“Choose your topping: ”)
LƯỢT CỦA BẠN: Thêm thông tin đầu vào cho người
dùng tới menu
Thêm các hàm input() vào menu. Sử dụng tên biến
thích hợp để lưu trữ câu trả lời của người dùng.
"Giờ thì sao anh?" Nó hỏi Simon.
"Bây giờ người dùng đã nhập một con số và em sẽ sử
dụng con số đó để tìm item. Trong Python, chúng ta gọi
con số này là chỉ mục danh sách – list index.
Nếu em đặt số này trong ngoặc vuông bên cạnh tên
danh sách, em sẽ nhận được item tương ứng. Giống như
thế này," Rồi anh viết ngay một mẫu code:

"Vì vậy sau khi em biết con số, em có thể tìm thấy mục -
item trong danh sách. Và em có thể in 'Đây là đơn đặt
hàng của bạn' như em đã làm ngày hôm qua, còn bây giờ
em lấy những item đó từ menu đi. Thử làm xem nào, anh
sẽ giúp em khi cần thiết."
Nó khó hơn một tý rồi. Erik nhìn vào chương trình ngày
hôm qua và sao chép các dòng rồi đặt xuống cuối
chương trình. Tiếp theo, cậu sửa các biến như drink
thành cấu trúc lệnh như Simon đã hướng dẫn.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Đây là các dòng code cậu vừa hoàn thành xong:


drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
drink = input(“Choose your drink: ”)
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
flavor = input(“Choose your flavor: ”)

print(“Erik’s Coffee Shop toppings”)


print(“------------------------”)
i=1
for t in toppings:
print(i, t)
i=i+1
topping = input(“Choose your topping: ”)
print(“Here is your order: “)
print(“Main product: “, drink[drink])
print(“Flavor: “, flavor[flavor])
print(“Topping: “, topping[topping])
print(“Thanks for your order! “)
“Bây giờ hãy thử chạy nó và xem nó mang lại cái gì cho
chúng ta đây” Simon bảo.
Erik kích [Run] và chương trình in menu đồ uống rồi
yêu cầu cậu lựa chọn. Chương trình chạy đang ổn. Erik
nhanh chóng nhập số cho cả ba menu và thấy kết quả
như hình sau:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Thế là thế nào anh?" Cậu cảm thấy bối rối.


"Xin chúc mừng!" Simon nói.
"Sao anh lại vui? Chương trình không hoạt động cơ mà?"
Erik cảm thấy tức giận với anh trai mình.
"Không sao đâu!" Simon đáp. "Em đã nhận được thông
báo lỗi đầu tiên từ Python và đó là một dấu hiệu tốt!
Phạm lỗi và sửa chúng là cách duy nhất để học hỏi. Em
đã nhận được một thông báo lỗi—bây giờ hãy cố gắng
khắc phục sự cố. Thông thường Python cung cấp cho em
lý do tại sao nó lại xảy ra như thế. Bắt đầu đọc từ dòng
nhắn cuối đi. Nó nói gì thế?"
"Cái gì đó về slice... Phải là số nguyên chứ không phải
str. Cái gì vậy trời?"
"Anh biết rồi, cần phải tập một chút để biết cách đọc các
thông báo lỗi Python. Ở đây chương trình cho em biết
rằng khi em sử dụng một biến làm chỉ mục của danh
sách [tức là số thứ tự trong item], biến đó phải có định
dạng là một số nguyên, như là một, hai, ba."
"Nhưng em đã nhập số rồi!" Erik vẫn còn bối rối
"Đúng là em đã gõ số trên bàn phím. Nhưng đối với
Python, mọi thứ em nhập từ bàn phím là định dạng một

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

chuỗi. Python tạo sự khác biệt giữa chuỗi chứa số '1' và


định dạng một số nguyên 1.”
“Điều này xuất phát từ cách máy tính lưu giữ mọi thứ
trong bộ nhớ,” Simon tiếp tục giảng giải.
"Máy tính giữ số 1 trong bộ nhớ, nhưng khi nó hiển thị
cho em, nó sẽ chuyển ‘1’ thành dạng chuỗi. Máy tính
chuyển đổi con số mà chúng nhận được từ bàn phím
theo một cách như vậy. Em gõ '123' trên bàn phím và
máy tính sẽ nhận chuỗi này và chuyển chuỗi này thành
dạng số 123. Hãy nhìn vào đây nè" Rồi Simon vẽ tranh
có hình máy tính, bàn phím, màn hình và người dùng.

Vì vậy, chúng ta nên yêu cầu Python chuyển đổi các


chuỗi em nhập trên bàn phím thành số nguyên. Có một
hàm đặc biệt gọi là int(). Để anh chỉ cho em cách dùng
nó."
Simon đã thay đổi một chỗ trong chương trình của Erik
và để cậu làm giống thế ở hai chỗ khác. Đây là chương
trình của Erik sau khi sửa:
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

toppings = [“chocolate”, “cinnamon”, “caramel”]


print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
drink = input(“Choose your drink: ”)
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
flavor = input(“Choose your flavor: ”)

print(“Erik’s Coffee Shop toppings”)


print(“------------------------”)
i=1
for t in toppings:
print(i, t)
i=i+1
topping = input(“Choose your topping: ”)
print(“Here is your order: “)
print(“Main product: “, drinks[int(drink)])
print(“Flavor: “, flavors[int(flavor)])
print(“Topping: “, toppings[int(topping)])
print(“Thanks for your order! “)
Erik chạy chương trình, nhập các lựa chọn của mình (cà
phê, caramel, sô cô la) và nhận được kết quả này:
Here is your order:
Main product: decaf
Flavor: vanilla
Topping: cinnamon
Thank for your order!
>>>
"Cái gì thế này? Không được rồi!" Erik kêu lên. "Đây
không phải lựa chọn của em!"
"Anh chưa nói với em một điểm quan trọng về danh
sách – list trong Python. Chỉ số - Index của chúng bắt

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đầu bằng số không chứ không phải là số một. Vì vậy nếu


em muốn lấy item đầu tiên trong danh sách, em cần đặt
số 0 trong dấu ngoặc vuông. Nếu em muốn item thứ hai,
em chọn số 1 cho chỉ số index.
"Nhưng tại sao lại thế??" Erik bị sốc bởi vụ kỳ quặc này.
"Đó là một câu chuyện dài," Simon trả lời. "Nó xuất phát
từ cách máy tính lưu trữ danh sách trong bộ nhớ.
Chỉ mục – Index của item em muốn chọn chính là số thứ
tự item em cần bỏ qua tính từ đầu danh sách. Nếu em
muốn item đầu tiên của danh sách, em không phải bỏ
qua bất kỳ item nào. Vị trí ngay đầu danh sách, item em
cần bỏ qua bằng không, đúng không nào? Đó là lý do tại
sao chỉ số của phần tử đầu tiên bằng không. Nhìn đây
nè" Simon vẽ luôn một bức tranh khác.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Vậy em nên làm gì bây giờ?" Erik hỏi. Cậu nghĩ rằng
mình đã hiểu lời giải thích của Simon, nhưng cậu ta vẫn
khó chịu vì sự bất tiện này.
"Anh thấy rằng em đang khó chịu," Simon nói. "Đừng lo
lắng, chả mấy rồi em sẽ quen với nó thôi. Rồi em sẽ,
giống như tất cả các lập trình viên thực thụ khác, bắt
đầu đếm mọi thứ từ con số không," Simon mỉm cười.
"Bây giờ em chỉ cần trừ 1 ở mỗi index trong ngoặc
vuông. Nhưng hãy cẩn thận: em phải thêm - 1 sau khi
em chuyển đổi đầu vào của mình thành số nguyên, chứ
không phải để nguyên định dạng như trước đó. Giống
thế này nhé: drinks [int(drink)-1]."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik đã sửa code của mình và bây giờ nó trông như hình
sau:
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
drink = input(“Choose your drink: ”)
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
flavor = input(“Choose your flavor: ”)

print(“Erik’s Coffee Shop toppings”)


print(“------------------------”)
i=1
for t in toppings:
print(i, t)
i=i+1
topping = input(“Choose your topping: ”)
print(“Here is your order: “)
print(“Main product: “, drinks[int(drink)-1])
print(“Flavor: “, flavors[int(flavor)-1])
print(“Topping: “, toppings[int(topping)-1])
print(“Thanks for your order! “)
LƯỢT CỦA BẠN: Sửa chương trình của bạn để in
đơn đặt hàng cho đúng
Sửa đổi chương trình tương tự như những gì Erik
vừa làm và in đơn đặt hàng. Đừng quên chuyển đổi
định dạng chuỗi đầu vào thành định dạng con số.
Đừng quên trừ một (1) từ mỗi số thứ tự —bởi index

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

list - chỉ mục danh sách bắt đầu bằng 0, nhớ đấy
nhé?
Erik chạy chương trình, nhập 2, 1, 1 và cuối cùng đã có
được thứ mình muốn:
Here is your order:
Main product: chocolate
Flavor: caramel
Topping: chocolate
Thank for your order!
>>>
"Tuyệt vời! Nó hoạt động rồi!" Erik chắc chắn đang rất
vui. "Em yêu chương trình quán cà phê rồi đấy! Chúng
ta đã xong nó chưa ạ?"
“Gần xong rồi” Simon trả lời. "Ta nhìn lại xem nào, em
đã viết gần như chính xác cùng một đoạn code những
ba lần."
"Liệu có gì sai ở đó không ạ?"
"Thử tưởng tượng thế này, tự dưng em muốn thay đổi
điều gì đó trong đoạn code của mình. Ví dụ: thay đổi
cách in các item trong menu. Em sẽ phải thay đổi nó ở
cả ba chỗ. Hoặc thậm chí ở nhiều chỗ hơn nữa nếu em
quyết định thêm list menu khác. Giả sử em muốn thêm
món tráng miệng - desserts vào quán cà phê của mình
đi. Điều đó có nghĩa là em sẽ phải sao chép đoạn code
này một lần nữa. Liệu điều gì sẽ xảy ra nếu em mắc lỗi
trong mã? Lập trình viên gọi chúng là bọ - bug (anh sẽ
cho em biết lý do sau). Thế là, em sẽ phải sửa lỗi đó ở
bốn chỗ, tự làm lặp đi lặp lại. Các lập trình viên tôn thờ

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

nguyên tắc DRY: Đừng lặp lại chính mình [Viết tắt của
cụm từ này Don’t Repeat Yourself]."
“Nhưng em không hiểu sẽ phải làm thế nào,” Erik thấy
bối rối. "Em có ba danh sách - list menu, em phải in ba
lần. Và em phải yêu cầu người dùng nhập dữ liệu ba
lần."
"Chúng ta có thể sử dụng một hàm ở đây," Simon giải
thích. "Em còn nhớ khi chúng ta bắt đầu sử dụng hàm
print(), anh đã nói rằng đối với các thao tác mà chúng ta
phải lặp đi lặp lại, chúng ta sẽ sử dụng hàm. Bấy đến giờ
chúng ta toàn dùng hàm người ta viết. Giờ thì chúng ta
sẽ tạo hàm của riêng mình rồi dùng ngay nó."
"Điều này hay đấy, em thích nó" Erik nói.
"Được rồi, hãy làm việc đó vào ngày mai. Anh nghĩ hôm
nay chúng ta đã làm đủ rồi. Em làm tốt lắm, Erik," Simon
thực sự vui mừng vì em trai mình đang tiến bộ. "Hãy
tóm tắt lại những gì chúng ta đã học hôm nay. Điều đầu
tiên là gì?"
“Đầu tiên, chúng ta tạo danh sách,” Erik đáp."Chúng ta
đưa tất cả drink, flavor and toppings vào danh sách."
"Tốt, tiếp theo là gì?"
"Sau đó, chúng ta in các danh sách bằng cách sử dụng
các vòng lặp. Rồi chúng ta in các con số thứ tự bên cạnh
mỗi đồ uống drink hoặc hương vị flavor."
"Đúng, chính xác" Simon xác nhận. "Tiếp đi em, sau đó
là cái gì?"
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Và rồi em đã thử in đồ uống từ danh sách, nhưng em


gặp lỗi từ Python. Và sau đó anh đã giải thích cho em
cách các con số được lưu trữ trong bộ nhớ máy tính như
thế nào. Tiếp nữa, chúng ta chuyển đổi sang định dạng
số và em in lại đơn đặt hàng. Tại anh không nói với em
rằng các chỉ số bắt đầu bằng số không," (Erik không
quên nhắc lại lỗi này!) "đơn đặt hàng của em đã bị in sai
tất cả các item!"
“Này, bỏ qua cho anh đê” Simon mỉm cười. "Nhưng bây
giờ em sẽ nhớ nó như in rồi, anh chắc chắn đấy!"
"Cuối cùng em đã sửa lại và bây giờ nó hoạt động tốt!"
Erik kết thúc.
"Em làm tốt lắm!" Simon giơ ngón tay cái lên với Erik.
"Chúng ta sẽ tiếp tục vào ngày mai và viết hàm đầu tiên
của chúng ta.”

2.1 Những điều mới mà bạn đã học được


ngày hôm nay

● Danh sách - List


Là tập hợp các mục - item trong Python. Bạn có thể có
các chuỗi hoặc con số trong danh sách hoặc thậm chí là
hỗn hợp cả hai.
● Số chỉ mục của danh sách – List index
Là con số chúng ta có thể sử dụng để truy xuất một
item từ danh sách. Các chỉ số trong danh sách luôn bắt
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đầu bằng 0 và tăng thêm một cho mỗi phần tử tiếp


theo: 0, 1, 2, 3, v.v.
● Định dạng số và định dạng chuỗi
Có nhiều loại biến khác nhau trong Python. Khi bạn in
một cái gì đó trên màn hình hoặc nhận đầu vào từ bàn
phím, chúng luôn là định dạng chuỗi. Nếu bạn muốn
làm bất kỳ phép toán nào với các con số mà ta nhận
được từ người dùng thì bạn phải chuyển đổi chúng từ
định dạng chuỗi thành định dạng số.

2.2 Code cho chương này

Bạn có thể tìm thấy code của chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch02

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Các hàm : Đừng lặp lại chính mình

Chương này bao gồm:


 Simon giải thích cách tránh lặp lại (và tại sao
3
phải thế)
 Erik viết hàm Python đầu tiên
 Erik bắt đầu sử dụng công cụ tương tác của
Python
 Erik cải thiện hàm của mình để làm cho hóa đơn
trông chuyên nghiệp hơn

"Hôm qua chúng ta dừng ở đâu nhỉ?" Simon hỏi Erik vào
ngày hôm sau.
"Anh nói rằng em không nên lặp lại. Và anh cũng nói
rằng chúng ta sẽ viết hàm riêng trong ngày hôm nay."
"Phải! Trước tiên, hãy cho anh biết những gì em biết về
hàm cho đến giờ này."
“Chúng ta đã sử dụng một vài hàm rồi,” Erik bắt đầu trả
lời. "Chúng ta dùng print() và intput() . Anh đã nói rằng
ai đó đã viết chúng để chúng ta sử dụng. Chúng ta có thể
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

sử dụng đối số với hàm. Chúng ta chỉ cần đặt chúng vào
giữa dấu ngoặc đơn và hàm sẽ làm điều gì đó với các đối
số, như là in chúng ra."
"Mọi thứ đều đúng! Em là một học sinh tuyệt vời!"
Simon mỉm cười. “Điều quan trọng về hàm là chúng có
thể làm điều tương tự cho các đối số khác nhau. Bởi thế
mà, nếu em thấy rằng một thứ đang cần làm đi làm lại
nhiều lần, em nên xem xét liệu nó có thể biến thành một
hàm không. Để quyết định, em cần xem mã code lặp của
mình và tự hỏi bản thân phần nào là giống nhau và phần
nào khác nhau. Đoạn code của em ngày hôm qua đâu
rồi?"
“Đây ạ,” Erik mở tập tin menu.py trong trình editor.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
print(“Erik’s Coffee Shop drinks”)
print(“----------------------”)
i=1
for d in drinks:
print(i, d)
i=i+1
drink = input(“Choose your drink: ”)
print(“Erik’s Coffee Shop flavors”)
print(“-----------------------”)
i=1
for f in flavors:
print(i, f)
i=i+1
flavor = input(“Choose your flavor: ”)

print(“Erik’s Coffee Shop toppings”)


print(“------------------------”)
i=1
for t in toppings:
print(i, t)
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

i=i+1
topping = input(“Choose your topping: ”)
print(“Here is your order: “)
print(“Main product: “, drinks[int(drink)-1])
print(“Flavor: “, flavors[int(flavor)-1])
print(“Topping: “, toppings[int(topping)-1])
print(“Thanks for your order! “)
"Hãy nhìn nè: điều gì đang lặp lại ở đây?" Simon hỏi và
bắt đầu vẽ sơ đồ các dòng code của Erik.

"Vòng lặp. Print() ở đầu và input() ở cuối."


"Liệu có gì khác nhau trong ba trường hợp này không?"
"Lời nhắc nhập dữ liệu cho input() thì khác ạ," Erik trả
lời. "Ngoài ra tiêu đề cũng hơi khác."
"Và em cũng đang chạy vòng lặp for qua các list khác
nhau, chẳng hạn như drink, flavor và topping, phải
không nào?” Simon quyết định giúp Erik một tay. "Vì
vậy, chúng ta sẽ truyền những thứ khác nhau làm đối
số. Trong trường hợp của ta, chúng sẽ là danh sách các
lựa chọn, tiêu đề menu và dòng nhắc nhập liệu."
“Hãy bắt đầu một tệp mới trong editor, đặt tên file là
menu_function.py rồi viết hàm của chúng ta vào đó."
Erik kích [New] trong trình chỉnh sửa, rồi [Save], gõ tên
menu_function.py rồi sẵn sàng viết code.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Các hàm trong Python bắt đầu bằng từ def theo sau là
tên của hàm,” Simon tiếp tục. "Hãy mở hàm menu của
chúng ta. Sau đó, em mở dấu ngoặc đơn và liệt kê các
đối số của mình."
Erik gõ def menu (và không chắc phải làm gì tiếp theo).
Simon ra tay giúp đỡ: "Chúng ta vừa nhắc tới những đối
số argument. Anh biết em đang nghĩ cách đặt tên cho
chúng. Hãy nhớ rằng, đặt tên biến và đối số là một trong
những vấn đề khó khăn nhất trong khoa học máy tính?
Em không cô đơn đâu. Hãy đặt tên cho chúng: choices,
title và prompt (lựa chọn, tiêu đề và dòng nhắc nhập
liệu.) Chỉ cần nhập chúng vào giữa các dấu ngoặc đơn và
đặt dấu hai chấm sau dấu đóng ngoặc."
Erik gõ như sau:
def menu(choices, title, prompt):
Cậu nhận thấy rằng sau khi nhấn ENTER, con trỏ di
chuyển đến dòng tiếp theo, thụt vào bên phải bốn dấu
cách space. "Em có nên viết ở đây không?" Cậu hỏi
Simon.
"Hoàn toàn được!" Simon đáp. "Em thấy đấy: trình biên
tập đang giúp em viết hàm! Bây giờ nhìn vào code ngày
hôm qua của em và bắt đầu sao chép những gì em muốn
đưa vào hàm. Nhìn nè: đầu tiên chúng ta in tiêu đề. Nào
chúng ta cùng làm điều đó ở đây, nhưng thay vì chuỗi
thực tế, chúng ta chỉ in đối số có tên là tiêu đề. Kể cả em

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

có đặt một đống dấu gạch ngang sau nó, giống như em
đã làm trước đây cũng được."
Erik gõ:
def menu(choices, title, prompt):
print(title)
print(“--------------------")
"Bây giờ hãy viết vòng lặp đi" Simon hướng dẫn.
"Nhưng thay vì đồ uống hoặc hương vị, danh sách của
em hiện được gọi là choices. Và em có thể sử dụng biến
c trong vòng lặp, là chữ cái đầu tiên của 'lựa chọn' ấy."
Erik đã sao chép vòng lặp từ đoạn code đã viết trước đó.
Cậu ấy đã có ý tưởng rồi, cậu thêm hàm input() với lời
nhắc prompt mà không cần hỏi anh trai mình.
def menu(choices, title, prompt):
print(title)
print(“--------------------")
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
"Tuyệt quá!" Simon nói khi nhìn thấy code của Erik.
“Bây giờ chúng ta phải trả về choice."
"Có phải chúng ta không thể in biến choice trong chương
trình chính ạ?" Erik hỏi.
"Không được! Đây cũng là một điều rất quan trọng về
hàm," Simon rất vui vì Erik đã hỏi câu này.
"Các biến em có bên trong hàm chỉ thấy được trong hàm
thôi. Nhìn kỹ đi nè, anh sẽ vẽ một bức tranh."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Khả năng visible (thấy) có nghĩa là em không thể nhìn


thấy các biến khi không ở trong hàm. Vì vậy, nếu chúng
ta muốn chương trình chính của ta thấy các giá trị của
chúng, chúng ta phải trả về các biến này.
Thông thường chúng ta có nhiều biến bên trong một
hàm, nhưng chúng ta chỉ muốn trả về một hoặc hai biến
kết quả. Trong trường hợp này, chúng ta có thể trả về
con số mà người dùng đã nhập, được lưu trữ trong biến
lựa chọn - choice"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon dừng lại và suy nghĩ một lúc.


"Nhưng chúng ta có thể làm tốt hơn," Anh nói. "Hãy xem
lại phần code ngày hôm qua của em nào. Có điều gì khác
nữa đang lặp lại không?"
Erik quan sát và trả lời: "Những hàm int() đó và cả hàm
mà chúng ta phải thêm -1 ba lần. Điều đó thật khó chịu,"
Cậu ấy vẫn chưa quen với thực tế là các chỉ số danh sách
bắt đầu bằng số không.
"Được rồi, cũng thêm chúng vào hàm luôn" Simon gợi ý.
"Chúng ta sẽ chuyển đổi câu trả lời của người dùng
thành số nguyên, nhận item từ danh sách và trả về item,
không phải là index của item. Điều đó sẽ làm cho hàm
của chúng ta thêm hữu ích hơn nữa. Chương trình chính
gọi hàm để nhận được sự lựa chọn của người dùng. Đó
không chỉ là chuyện của các con số. Để anh chỉ cho em
thấy" Simon thêm ngay các thao tác chuyển đổi và câu
lệnh return tới hàm.
def menu(choices, title, prompt):
print(title)
print(“--------------------")
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
answer=choices[int(choice)-1]
return answer
"Bây giờ chúng ta hãy cùng nhau kiểm tra nó đã" Simon
nói. "Ở bên dưới hàm trong chương trình chính, ta sẽ
gọi hàm ra và in câu trả lời mà chúng ta nhận được.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Nhưng trước tiên, chúng ta cần các danh sách đồ uống


và các thứ khác. Sao chép hết – Copy all cả đoạn code
trong chương trình ngày hôm qua đã làm đi em."
Erik thêm vào ba danh sách ngay bên dưới hàm. Lần này
tất cả các dòng không thụt lề vào bên trong.
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
“Tốt rồi” Simon giảng giải. "Bây giờ em đã sẵn sàng gọi
hàm của mình rồi. Truyền tiêu đề, danh sách đồ uống,
và gợi ý đầu vào [chính là title, list of drink, prompt]. Kết
quả từ hàm gán cho một biến. Ví dụ gọi nó là choice. Rồi
thì in nó ra."
Erik đã làm theo hướng dẫn của Simon và đây là những
gì cậu ấy có:
def menu(choices, title, prompt):
print(title)
print(“--------------------")
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
answer=choices[int(choice)-1]
return answer
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
choice = menu(drinks, “Erik’s drinks”, “Choose your drink: “)
print(choice)
LƯỢT CỦA BẠN: Tạo hàm của riêng bạn
Tạo hàm của riêng bạn tương tự như mấy dòng Erik
vừa tạo. Sử dụng danh sách menu, tiêu đề và lời gợi
ý. Thử chạy nó xem (làm trước Erik nhé!).
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Em chạy chương trình nhé?" Erik hỏi.


"Chạy đi, nó đã sẵn sàng, làm tới luôn đi em!"
Erik kích [Run] và chương trình hỏi cậu về đồ uống,
giống hệt như cách nó đã hỏi trước đây. Erik trả lời và
nhận được kết quả như mong đợi.
Erik’s drinks
--------------------
1 chocolate
2 coffee
3 decaf
Choose your drink: 2
coffee
>>>
"Nó hoạt động rồi!" Cậu thốt lên. "Em sẽ thêm các menu
khác vào luôn đây" Cậu lại gõ tiếp. Mất độ chừng 10
phút, Erik hoàn toàn sẵn sàng để test toàn bộ chương
trình. Bây giờ chúng ta có chương trình như trong hình:
def menu(choices, title, prompt):
print(title)
print(“--------------------")
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
answer=choices[int(choice)-1]
return answer
drinks = [“chocolate”, “coffee”, “decaf”]
flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
drink = menu(drinks, “Erik’s drinks”, “Choose your drink: “)
flavor = menu(flavors, “Erik’s flavors”, “Choose your flavor: “)
topping = menu(toppings, “Erik’s toppings”, “Choose your topping: “)
print(“Here is your order: “)
print(“Main product: “, drink)
print(“Flavor: “, flavor)
print(“Topping: “, topping)
print(“Thanks for your order!“)
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Thêm các menu khác


Thêm các menu khác vào chương trình. Ta dùng
cùng một hàm với các đối số khác nhau: danh sách
các lựa chọn, tiêu đề và lời nhắc hướng dẫn. Hãy thử
chạy nó và kiểm tra với các lựa chọn của bạn.
Thế rồi chương trình hoạt động như mong đợi! Erik
chạy chương trình, nhập 2, 2, 1 và nhận đơn hàng:
Here is your order:
Main product: coffee
Flavor: vanilla
Topping: chocolate
Thank for your order!
>>>
Simon nói: "Em có thấy chương trình đã trở nên ngắn
hơn chưa. Giờ đây nếu em phải thay đổi một cái gì đó,
em chỉ thay đổi nó ở một nơi thôi."
"Tại sao em lại muốn thay đổi nó? Nó đã hoạt động tốt
rồi mà" Erik hỏi.
"Ồ, có nhiều cách để cải thiện code lắm!" Simon trả lời.
"Hãy làm cho tiêu đề của chương trình đẹp hơn một
chút nữa. Em có nhận thấy rằng dòng gạch ngang của
em đang dài hơn tiêu đề không?"
"Thật thế à? Ồ, vâng, anh nói đúng" Erik trả lời. "Đó là
bởi vì em đã đổi tiêu đề thành 'Đồ uống của Erik'.
Em có thể đổi để nó ngắn hơn, làm cái đó dễ mà."
"Chắc chắn rồi, em có thể làm cho nó ngắn hơn, nhưng
hãy quan sát - trong menu 'drinks', tiêu đề ngắn hơn,

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

trong menu ‘toppings’ nó dài hơn. Em nên in dòng gạch


ngang có cùng độ dài với phần tiêu đề."
"Thế em nên làm thế nào đây? Có lẽ, nên loại bỏ đường
gạch ngang ấy đi thì tốt hơn?" Erik bối rối.
"Không, anh thích cái dòng gạch đó; nó làm cho hóa đơn
trông thật hơn. Anh muốn em giữ nó lại. Chỉ là chúng ta
cần tính toán độ dài của tiêu đề và làm cho hai thứ có
cùng độ dài với nhau. Chúng ta sẽ học một hàm mới và
một thao tác mới ở đây. Hàm chúng ta sẽ sử dụng có tên
là len(). Em chỉ cần đặt một đối số chuỗi bên trong dấu
ngoặc đơn và nó sẽ trả về độ dài của chuỗi. Để anh chỉ
cho em nhé. Chúng ta sẽ sử dụng một tính năng khác của
Mu Editor, được gọi là REPL. Nó là viết tắt của 'Read-
Eval-Print-Loop' và có nghĩa là em có thể sử dụng
Python Interactive[Chú thích: Vòng lặp Đọc-Đánh giá-
In, hay REPL, là một môi trường máy tính nơi đầu vào
của người dùng được đọc và đánh giá, sau đó kết quả
được trả về cho người dùng. REPL cung cấp một môi
trường tương tác để khám phá các công cụ có sẵn trong
các môi trường hoặc ngôn ngữ lập trình cụ thể]. Anh
thường sử dụng nó khi anh muốn kiểm tra một cái gì đó
một cách nhanh chóng. Hoặc để cho người lập trình xem
cái gì đó, như bây giờ đây này" và Simon mỉm cười.

"Kích [REPL] REPL ," Simon tiếp tục.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik kích và một cửa sổ khác mở ra tại dưới cùng cửa sổ


Mu Editor.

“Em thấy đấy - em có Python Interactive [Python tương


tác] ở đây," Simon nói. "Em có thể nhập bất kỳ mã
Python nào vào đây và nó sẽ được thực thi. Thậm chí là
em có thể sử dụng nó như một máy tính cầm tay" Simon
cười. "Gõ thử print('hello world') hoặc 2+2 mà xem.”
Erik gõ và Simon đúng rồi!
In[1]: print(‘hello world’)
hello world
In[2]: 2+2
Out[2]: 4
"Bây giờ ta tính độ dài của một chuỗi. Nhập:
len('abcd')”
Erik gõ lệnh và nhận lại kết quả:
In[3]: len(‘abcd’)
Out[3]: 4
"Bây giờ em nhìn thấy độ dài của chuỗi 'abcd' là 4,"
Simon nói. "Em cũng làm tương tự với các biến chuỗi.
Sử dụng biến s, đặt chuỗi 'xin chào' vào hàm để tính độ

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

dài của nó. Anh chắc rằng bây giờ em đã biết cách thực
hiện thế nào rồi."
Erik gõ vào cửa sổ REPL và nhận được kết quả:
In[4]: s = ‘hello’
In[5]: len(s)
Out[5]: 5
“Tốt,” Simon nói. "Chắc giờ em đã hiểu nếu em có một
sợi dây, em luôn biết được độ dài của nó. Hơn nữa, em
có thể lấy độ dài của danh sách theo cách này. Tạo một
danh sách các số: 1, 2, 3 và lấy chiều dài. Gọi nó là n
chẳng hạn."
Erik gõ:
In[6]: n = [1, 2, 3]
In[7]: len(n)
Out[7]: 3
“Chúng ta sẽ sử dụng nó sau, còn bây giờ để anh chỉ cho
em một mẹo,” Simon tiếp tục giảng giải. "Python sẽ cho
ta cái gì nếu em yêu cầu nó lấy số 2 và nhân nó với 2?"
"4?" Erik không chắc đó có phải là một câu hỏi mẹo hay
không. Câu hỏi đơn giản quá.
"Phải. Python sẽ cho em cái gì nếu em lấy một chữ cái
'A' và nhân nó với 2?"
"Em không biết? 2A, có lẽ vậy chăng?
"Làm đi nào và thử với Python interactive xem sao!"
Simon gợi ý.
Erik gõ và nhận được kết quả:
In[8]: 2*’A’
Out[8]: ‘AA’
"Hấp dẫn thật đấy!" Erik ngạc nhiên.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Bây giờ nếu em lấy dấu gạch ngang thay vì 'A' và nhân
với 10 thì sao?"
Erik bắt đầu phỏng đoán xem Simon đang dẫn mình đến
đâu và cậu gõ:
In[9]: 10*’-’
Out[9]: ‘----------'
"Và bây giờ hãy thay thế số 10 bằng độ dài của chuỗi
'hello'."
Erik đã hiểu được ý của Simon và cậu gõ máy:
In[10]: len(‘hello’)*’-’
Out[10]: ‘-----’
LƯỢT CỦA BẠN: Sử dụng REPL và thử nghiệm với
hàm len()
Bắt đầu REPL bằng cách kích vào biểu tượng của nó
trong Editor. Lặp lại tất cả các thử nghiệm của Erik.
Thử nhân một số với một chuỗi gồm hai hoặc ba chữ
cái. Liệu bạn có đoán đầu ra sẽ là gì không?
"Em thấy rõ rồi chứ!" Anh hỏi. "Chúng ta lấy đối số là
title, chúng ta tính toán độ dài của nó và chúng ta in
dòng gạch ngang có cùng kích thước y hệt!"
"Liệu bây giờ em có sửa hàm được không?" Simon hỏi.
"Vâng, chắc chắn được, em biết phải làm gì rồi!" Erik bắt
đầu gõ lệnh. Cậu ấy chỉ thay đổi dòng thứ ba (tìm nhãn
1) và bây giờ hàm trông như hình bên dưới:
def menu(choices, title, prompt):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

choice=input(prompt)
answer=choices[int(choice)-1]
return answer
LƯỢT CỦA BẠN: Sửa hàm để in đúng độ dài của
dòng gạch ngang
Thực hiện chỉnh sửa trong chương trình để in đúng
số dấu gạch ngang, giống hệt với những gì Erik vừa
làm. Hãy thử dùng một ký hiệu khác (dấu bằng =
hoặc dấu gạch dưới _ hoặc ký hiệu khác).
Cậu ấy đã thử nghiệm chương trình chính và bây giờ tất
cả các dòng gạch ngang đều có cùng kích thước với tiêu
đề.
Simon nhận xét, "Bây giờ em thấy rằng không chỉ kết
quả hàm của em trả về phụ thuộc vào các đối số, mà
ngay cả những gì nó in ra cũng phụ thuộc như thế."
"Phân tích các đối số mà em nhận được trong hàm luôn
là một ý kiến hay," Simon tiếp tục. "Trong trường hợp
này, chúng ta đã kiểm tra độ dài của tiêu đề. Hàm của
em sẽ làm gì nếu nhận được một chuỗi rỗng có độ dài
bằng 0?"
“Em không biết,” Erik trả lời. "Em nghĩ nó sẽ in ra một
chuỗi rỗng, chuỗi không có gì."
“Đúng thế” Simon đáp. "Có lẽ chúng ta vẫn nên in ra một
cái gì đó hợp lý, ngay cả khi tiêu đề là là rỗng. Có thể chỉ
là một từ 'Menu' và một dòng gạch ngang. Đối với những
trường hợp như vậy trong Python, chúng ta có các giá
trị mặc định cho các đối số của hàm. Trong hàm của em,
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

anh sẽ thay đổi dòng đầu tiên thành thế này," Simon
chỉnh sửa tệp của Erik:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
"Trong trường hợp này, chúng ta nói với Python, title
nhận giá trị nếu có đối số. Còn nếu em không sử dụng
đối số khi gọi hàm ra, thì hãy sử dụng giá trị mặc định,
chỉ cần gán là 'Menu' cũng được. Chương trình thường
khuyến nghị đặt giá trị mặc định. Em có thể thay đổi
chúng thành cái khác khi em gọi hàm."
"Hãy test nó đi" Simon gợi ý. "Lần gọi đồ uống đầu tiên,
hãy xóa cả tiêu đề và lời nhắc hướng dẫn. Chỉ để lại đồ
uống là một đối số duy nhất." Erik làm theo gợi ý của
Simon và bây giờ lời gọi hàm lần đầu tiên trông như thế
này:
drink = menu(drinks)
Cậu chạy lại chương trình và nhìn thấy menu đầu tiên:
Erik’s Menu
----------
1 chocolate
2 coffee
3 decaf
Choose your item:
Đây là chương trình đầy đủ của Erik.
Listing 3.1 menu_function.py
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*“-")
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
answer=choices[int(choice)-1]
return answer

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

drinks = [“chocolate”, “coffee”, “decaf”]


flavors = [“caramel”, “vanilla”, “peppermint”, “raspberry”, “plain”]
toppings = [“chocolate”, “cinnamon”, “caramel”]
drink = menu(drinks, “Erik’s drinks”, “Choose your drink: “)
flavor = menu(flavors, “Erik’s flavors”, “Choose your flavor: “)
topping = menu(toppings, “Erik’s toppings”, “Choose your topping: “)
print(“Here is your order: “)
print(“Main product: “, drink)
print(“Flavor: “, flavor)
print(“Topping: “, topping)
print(“Thanks for your order!“)
LƯỢT CỦA BẠN: Sử dụng các đối số mặc định trong
hàm
Thêm giá trị mặc định cho đối số tiêu đề và lời nhắc
hướng dẫn. Hãy dùng các hàm của bạn với việc
không có các đối số đó và đảm bảo rằng nó sử dụng
các giá trị mặc định.
"Tất nhiên, nó không nói với người dùng rằng đó là
menu đồ uống nhưng rõ ràng vẫn tốt hơn là chỉ để một
chuỗi trống rỗng. Giá trị mặc định khá hữu ích khi bạn
muốn test nhanh chương trình. Bởi lúc nào muốn em
cũng có thể gõ thêm mô tả tiêu đề và lời nhắc hướng
dẫn."
"Anh nghĩ thế là đủ cho ngày hôm nay rồi" Simon nói.
"Hãy tóm tắt lại những gì chúng ta đã học vừa rồi. Việc
đầu tiên hôm nay là gì?"
"Chúng ta đã xem xét chương trình, nó được viết ngày
hôm qua và em tìm thấy những thứ được lặp lại ba lần.
Thế là anh đã nói với em rằng chúng ta có thể viết hàm

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của riêng mình. Anh đã nói với em về từ khóa def và các


đối số."
“Tốt, tiếp tục đi,” Simon khuyến khích Erik. "Còn đối số
thì sao?"
"Em đã sử dụng danh sách các lựa chọn, tiêu đề và lời
nhắc làm đối số trong hàm." Erik thích nói về các hàm
của cậu ấy - cậu đã tự viết hàm đầu tiên!
“Sau đó, anh đã cho em xem cái REPL trong trình chỉnh
sửa,” Erik tiếp tục nói. "Em thích nó! Rồi sau đó chúng
ta tính toán độ dài của chuỗi."
"Thế chúng ta đã dùng nó để làm gì?" Simon hỏi.
"Vâng, chúng ta dùng nó để in hóa đơn và bây giờ chúng
trông đẹp rồi. Sau đó, chúng ta thử sử dụng các giá trị
mặc định cho các đối số. Nó hơi nhàm chán nhưng hiệu
quả."
Simon nói: "Đây là một điều rất quan trọng mà em vừa
nói. Xử lý để chương trình tốt lên nhìn có vẻ nhàm chán.
Mà thế đấy, lập trình không phải lúc nào cũng là về các
thủ thuật hay và hack. Hầu hết thời gian em phải làm
những việc rất nhàm chán, như kiểm tra đầu vào của
người dùng, kiểm tra lỗi và cứ như vậy. Mà nếu làm công
việc nhàm chán này khiến chương trình hoạt động được
thì nó đáng giá. Ngày mai chúng ta sẽ xem chúng ta phải
làm gì để đảm bảo chương trình của em hoạt động ngay
cả khi người dùng của em nhập sai giá trị. Nhưng bây

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

giờ - hãy nghỉ ngơi một chút! Hôm nay, em thực hiện tốt
rồi!

3.1 Những điều mới mà bạn đã học được


ngày hôm nay

● Hàm
Là một đoạn code lập trình được sử dụng (được gọi)
nhiều lần. Một hàm hoặc do bạn hoặc do người khác
viết. Nếu nó được viết bởi người khác thì nó thường là
một phần của thư viện hoặc một modules trong Python.
● Đối số
Là các biến mà chúng ta truyền vào hàm khi chúng ta
gọi nó. Hàm lấy các đối số và sử dụng chúng để chuẩn bị
đầu ra. Đầu ra có thể được in hoặc trả về chương trình
chính.
● REPL
Là Read-Eval-Print-Loop, một cách để chạy Python
tương tác. Nó rất hữu ích để kiểm tra nhanh một hàm.

3.2 Code cho chương này

Bạn có thể tìm thấy code cho chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch03

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

4
Lỗi người dùng: Ai cũng có thể mắc lỗi

Chương này bao gồm


 Erik phát hiện ra rằng không phải lúc nào người
dùng cũng làm theo những gì bạn hướng dẫn
 Erik học cách sử dụng vòng lặp để lặp lại câu hỏi
của mình cho người dùng
 Simon giúp Erik làm menu phong phú hơn

“Hôm qua em làm tốt lắm, Erik ạ” Simon tiếp tục hướng
dẫn vào ngày hôm sau. "Em đã viết một hàm hữu ích,
em đã thêm các đối số mặc định, em đã test thử."
“Vâng,” Erik trả lời. "Em nghĩ đó là một chương trình
hay. Em muốn cho bạn bè xem!"
“Từ từ đã” Simon nói. "Anh nghĩ nó chưa sẵn sàng để sử
dụng đâu."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Sao cơ ạ? Em tưởng nó hoạt động hoàn hảo rồi!"


"Ồ, thế á? Để anh thử xem nhé" Simon trông như đang
suy nghĩ điều gì đó. Anh bật chương trình của Erik và tại
menu đầu tiên anh nhập: "Cà phê"

"Anh làm cái gì đấy???" Erik đã rất tức giận. "Anh phải
nhập số chứ đừng nhập chữ!"
"Nhưng em đưa cho anh một danh sách và hỏi anh
muốn gì mà. Anh muốn cà phê nên anh đã nhập 'cà phê'.
Làm sao vậy?" Simon cố tỏ ra ngây thơ nhưng anh
không thể giấu được nụ cười của mình.
"Haizz, đối với những người dùng ngu ngốc như vậy, em
sẽ viết IN HOA bảo rằng nên nhập MỘT CON SỐ!" Erik
càu nhàu.
"Được, được, để anh thử lại," Simon hỏi. Anh ấy bắt đầu
lại chương trình và ở menu đầu tiên anh gõ: "42".

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Lại nữa?? Anh tính tạo lỗi à??" Erik đã sẵn sàng đập vào
tay Simon trên bàn phím. "Anh không thấy rằng chỉ có
ba sự lựa chọn sao? Tại sao anh nhập 42??"
"Thứ nhất, vì 42 là con số yêu thích của anh. Thứ hai,
đúng vậy, anh biết đó là lỗi của anh. Em biết mà – một
người dùng mắc lỗi. Nghiêm túc mà nói, anh muốn cho
em thấy rằng chương trình của em cần sẵn sàng cho sai
lầm. Em có thể in bất cứ thứ gì em muốn, viết hoa toàn
bộ, nhưng vẫn sẽ có những người dùng không đọc nó.
Vẫn có những người dùng mắc sai lầm."
"Trường hợp này em nên làm gì?" Erik vẫn còn tức giận
với anh trai mình, nhưng cậu ấy có xu hướng đồng ý với
ông anh. Chính cậu tạo nên một chương trình có lỗi.
"Em nên kiểm tra những gì người dùng nhập vào và
thông báo cho họ nếu thông tin nhập sai. Hãy nghĩ xem
chúng ta có thể làm gì chỗ này.

4.1 Nếu người dùng của bạn không làm


những gì bạn mong đợi

"Em nghĩ người dùng nên nhập gì trong menu đầu


tiên?" Simon nói tiếp.
“Họ cần nhập 1, 2 hoặc 3,” Erik trả lời.
"Được rồi, vì vậy chúng ta có thể kiểm tra xem câu trả
lời của họ là '1', '2' hay '3', sau đó chúng ta truyền nó và

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

nhặt lấy item trong list lựa chọn. Nếu không phải vậy,
chúng ta cần nói với người dùng rằng có gì đó không
đúng ở đây."
"Vâng, em nhớ rồi, chúng ta có thể sử dụng if-else trong
Python," Erik đề xuất.
"Được rồi, thử chút đi," Simon nói. "Em sẽ làm điều đó
như thế nào? Hãy giải thích cho anh coi như anh chưa
biết gì về if-else nhé.”
"Em sẽ thêm vào chức năng thế này: 'Nếu lựa chọn của
người dùng là 1, hoặc 2 hoặc 3, thì hãy tiếp tục và sử
dụng nó. Nếu không (else), hãy in ra thông báo người
dùng nên nhập một trong những số trên'."
"Được, cùng nhau soạn code nào" Simon nói.
Erik mở trình soạn thảo lên và thay đổi hàm (bốn dòng
ngay trước return):
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
if choice==’1’ or choice==’2’ or choice==’3’:
answer=choices[int(choice)-1]
else:
print(“Enter number 1, 2 or 3!”)
return answer
"Bây giờ hãy test nó," Simon nói.
Erik bắt đầu chương trình và tại menu đầu tiên cậu gõ:
"2".
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tại sao em nhập '2'?" Simon hỏi.


“Bởi vì em muốn uống cà phê,” Erik trả lời.
"Nhưng chúng ta đang kiểm tra chương trình của em để
tìm câu trả lời sai!" Simon nói. "Được rồi, anh biết đó là
chương trình của em mà em không muốn phá vỡ nó,
nhưng với tư cách là nhà phát triển, em phải cố gắng
phá vỡ chương trình của mình.
Em phải tưởng tượng tất cả những cách mà người dùng
của em có thể xảy ra nếu chương trình của em chạy sai.
Cảm giác ấy mệt mỏi và khó chịu, anh biết, nhưng em
phải vượt qua và cố gắng xử lý tất cả các lỗi sai có thể
xảy ra."
“Được rồi, được rồi,” Erik nói và khởi động lại chương
trình. Ở menu đầu tiên, cậu gõ vào con số "42" giống
như Simon đã làm lần trước.

“Hãy xem chuyện gì đang xảy ra ở đây,” Simon nói. "Đầu


tiên, khi em nhập '42', chương trình của em in ra thông
báo rằng người dùng chỉ nên nhập 1, 2, 3. Điều này tốt.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Nhưng sau đó có gì đó không ổn. Nhìn này, nó nói rằng


biến answer đã được tham chiếu trước khi gán giá trị:

Nói một cách đơn giản, điều đó có nghĩa là em không tạo


ra answer mà em đã cố gắng sử dụng nó. Và Python chỉ
cho em chính xác ở đâu: em đã cố trả về answer nhưng
Python không biết gì về biến answer”
“Tại sao lại thế?” Erik nói. "Em có answer này = dòng
lệnh trong mã rồi mà."
"Đúng, em đã làm rồi nhưng điều quan trọng là dòng
này được sử dụng ở đâu. Trong code của em, em chỉ tạo
biến answer khi người dùng nhập lựa chọn đúng. Nếu
người dùng nhập một cái gì đó sai khác, thì biến answer
thậm chí còn chưa kịp tạo ra."
"Nói cách khác," Simon tiếp tục giảng giải "Ngay cả khi
người dùng trả lời sai con số, hoặc thậm chí sai một từ,
em vẫn phải trả về vài cái answer. Đó là một quy tắc rất
quan trọng: đừng bao giờ sử dụng biến trước khi em
tạo ra và gán một số giá trị cho nó. Liệu chúng ta có thể
gán giá trị nào cho answer ở đây trong trường hợp
người dùng bị lỗi? Anh nghĩ rằng một chuỗi rỗng thế
này ‘ ’ nên đặt ở đây. Thêm nó vào hàm của em xem rồi
kiểm tra xem nó có giúp được gì hay không."
Erik đã sửa hàm như hình bên dưới:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

for c in choices:
print (i, c)
i = i+1
choice=input(prompt)
if choice==’1’ or choice==’2’ or choice==’3’:
answer=choices[int(choice)-1]
else:
print(“Enter number 1, 2 or 3!”)
answer=’’
return answer
LƯỢT CỦA BẠN: Kiểm tra answer của người dùng
Ở trong hàm menu của bạn, hãy thêm code mà Erik
vừa thêm vào. Kiểm tra xem nó đã thực kiểm tra câu
trả lời của bạn hay chưa.
Cậu ấy đã test lại chương trình và lần này nó không báo
lỗi nữa. Nó in thông báo Hãy nhập số 1,2 hoặc 3! và
chuyển sang menu tiếp theo.
"Em có nghĩ rằng chương trình đã làm đúng chưa?"
Simon hỏi.
“Nó đã in câu bạn nên nhập 1, 2 hoặc 3” Erik trả lời. “Em
nghĩ đúng rồi”
"Mà em chưa nhận được lựa chọn đồ uống của người
dùng. Nếu họ nhập sai số, em nên cho họ cơ hội nhập
đúng. Đây không phải là một bài kiểm tra như ở trường
mà em chỉ có một cơ hội để trả lời. Em nên tiếp tục hỏi
người dùng cho đến khi em nhận được một trong những
câu trả lời đúng."
"Có cách nào làm được như thế ạ?" Erik hỏi.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Chúng ta có loại vòng lặp khác để có kết quả như thế,”


Simon bắt đầu giải thích cho em trai mình. "Nó được gọi
là vòng lặp while. Nó lặp đi lặp lại một điều gì đó và với
mỗi chu kỳ nó sẽ kiểm tra điều kiện. Khi điều kiện đúng,
nó sẽ tiếp tục. Nếu điều kiện sai, vòng lặp while kết thúc.
Có lúc chúng ta kiểm tra điều kiện ngay từ đầu vòng lặp
nếu chúng ta đã biết rồi. Lúc này thì, chúng ta nói 'Nó
vẫn còn đúng, hãy làm đi'. Nhưng cũng có lúc, hệt như
trường hợp này, chúng ta chưa có câu trả lời khi bắt đầu
vòng lặp vì chúng ta vẫn chưa hỏi người dùng về lựa
chọn của họ. Vì vậy, chúng ta bắt đầu một vòng lặp vô
hạn và kiểm tra điều kiện bên trong vòng lặp sau khi
chúng ta nhận được câu trả lời từ người dùng. Chúng ta
thoát khỏi vòng lặp nếu điều kiện trở thành đúng.
Chúng ta gọi nó là phá vỡ - break vòng lặp. Để anh biểu
diễn nó bằng sơ đồ" Simon nói và bắt đầu vẽ.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon giải thích: "Trong ví dụ này, chúng ta đã biết điều


kiện trước khi bắt đầu vòng lặp. Chúng ta kiểm tra điều
kiện và quyết định xem có nên bắt đầu hay không. Nó
cần là True, nếu không thì vòng lặp không cần bắt đầu.
Anh dùng một hình thoi để kiểm tra điều này; đây là
cách các lập trình viên tiến tới quyết định lập trình.”
"Nếu đó là true thì chúng ta sẽ làm gì đó. Điều quan
trọng là một trong những 'điều gì đó' này sẽ thay đổi
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

điều kiện. Nếu không thì vòng lặp sẽ tiếp tục mãi mãi và
chúng ta không muốn điều đó.”
"Sau khi hoàn thành 'điều gì đó', chúng ta quay lại đầu
vòng lặp và kiểm tra lại điều kiện. Nếu điều kiện vẫn
đúng, chúng ta lặp lại 'điều gì đó'. Nếu không, đó là phần
cuối của vòng lặp và chúng ta nhảy ra ngoài đó để tiếp
tục chương trình.”
"Hãy xem ví dụ đơn giản này: chúng ta muốn đếm
ngược từ năm đến không. Đầu tiên, chúng ta đặt biến n
bằng năm và khi bắt đầu vòng lặp, chúng ta kiểm tra
xem nó có lớn hơn 0 không. Rồi, nó lớn hơn, vậy chúng
ta bắt đầu vòng lặp. Nhớ là điều kiện phải thay đổi tại
một chỗ nào đó, nếu không thì vòng lặp sẽ không bao
giờ kết thúc. Trong ví dụ này, chúng ta trừ 1 cho mỗi lần
đi qua vòng lặp. Cuối cùng biến n sẽ bằng 0 và vòng lặp
sẽ dừng lại.
"Điều quan trọng là trong trường hợp này, trước khi
chúng ta bắt đầu vòng lặp, chúng ta đã biết giá trị của
biến và chúng ta biết rằng nó lớn hơn 0.
"Điều gì sẽ xảy ra nếu chúng ta không biết những gì
trong biến hoặc thậm chí không tồn tại cả biến nữa?
Như trong trường hợp này: chúng ta chỉ có thể kiểm tra
câu trả lời của người dùng sau khi chúng ta yêu cầu
chọn một trong các item từ menu. Vì vậy, chúng ta phải
làm thế này" Rồi Simon vẽ ra một sơ đồ khác.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon tiếp tục giải thích: "Ở đây chúng ta bắt đầu vòng
lặp mà không cần kiểm tra bất kỳ điều kiện nào. Chúng
ta làm điều gì đó trước và sau đó chúng ta mới kiểm tra
điều kiện. Đôi khi vòng lặp này được gọi là 'do-until', có
nghĩa là 'làm điều gì đó cho đến khi điều kiện là true'.
Khi điều kiện là đúng, thoát khỏi vòng lặp và tiếp tục với
phần còn lại của chương trình.
Trong ví dụ ở đây, anh đã sử dụng tình huống của em
với input(). Em yêu cầu đầu vào, sau đó em kiểm tra đầu
vào đó. Đây là điều kiện của em: nếu đầu vào hợp lệ, em

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

nên thoát khỏi vòng lặp. Trong Python, chúng ta sử


dụng lệnh break để thoát ra.”
Erik hơi choáng ngợp trước những lời giải thích lòng
vòng này, nhưng cậu ta cảm thấy đã tự biết phải làm gì.
Cậu hỏi anh trai, "Tức là theo anh, em chỉ nên đặt while
trước dòng input() và thêm break sau khi em nhận được
câu trả lời đúng?"
"Đúng rồi" Simon đáp, "Hoàn toàn đúng! Chỉ cần đừng
quên thụt lề sang bên phải tất cả các dòng thuộc phần
vòng lặp là bốn space. Trình editor sẽ giúp em, không
cần lo lắng vụ này."
Erik bắt đầu làm việc với chương trình. Sau vài phút,
hàm của cậu trông như thế này:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
while True:
choice=input(prompt)
if choice==’1’ or choice==’2’ or choice==’3’:
answer=choices[int(choice)-1]
break
else:
print(“Enter number 1, 2 or 3!”)
answer=’’
return answer
“Đúng chưa anh?" Erik hỏi anh trai.
"Anh đã nói với em rồi, rằng trình editor sẽ giúp mình

mà. Kích Check để kiểm tra đi."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik làm theo gợi ý của anh trai và thấy điều này:

"Bây giờ em thấy chưa?" Simon nói. "Em quên thụt lề


các dòng sang bên phải. Đó là lý do tại sao nó nói rằng
nó mong đợi một khối thụt lề ở đây. Dịch chuyển tất cả
các dòng là một phần của vòng lặp sang bên phải."
Erik sửa hàm và kiểm tra lại code.
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
while True:
choice=input(prompt)
if choice==’1’ or choice==’2’ or choice==’3’:
answer=choices[int(choice)-1]
break
else:
print(“Enter number 1, 2 or 3!”)
answer=’’
return answer

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Thêm vòng lặp while vào hàm


của bạn
Thêm vòng lặp như Erik vừa làm. Thử dùng nút
Kiểm tra - Check để tìm xem có lỗi trong đoạn
code không. Hãy tạo lỗi và xem xem liệu trình
editor có thể tìm thấy chúng không.

Nút Kiểm tra - Check hiển thị biểu tượng ngón tay
cái màu xanh lá cây hiện lên lúc này khiến Erik biết là
đã ổn rồi. Cậu bấm Run để chạy thử chương trình. Ở
menu đầu tiên, cậu nhập '42' giống như Simon đã làm
lần trước. Chương trình thông báo cậu nên chọn một số
1, 2 hoặc 3 và quay lại dấu nhắc lệnh một lần nữa! Nó
không tiêu tùng mà đã hoạt động rồi!
"Mỗi lỗi nữa mà anh Simon đã làm với chương trình
mình là gì nhỉ?" Erik cố nhớ lại. "Đúng rồi, anh ấy đã
từng nhập từ 'cà phê'! Nào thử nào."
Cậu ấy nhập từ 'cà phê' và chương trình đã phản hồi như
mong đợi! Cuối cùng Erik gõ '2' và menu tiếp theo hiện
ra. Đây là những gì cậu ấy nhìn thấy trong cửa sổ soạn
thảo (Chúng ta đánh dấu đầu vào của Erik bằng chữ in
đậm):
Erik’s Menu
----------
1 chocolate
2 coffee
3 decaf
Choose your item: 42
Enter number 1, 2 or 3!
Choose your item: coffee

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Enter number 1, 2 or 3!
Choose your item: 2
Erik’s flavor
-----------
Ở menu tiếp theo, anh ấy gõ 4 chọn Raspberry và nhận
được thông báo tương tự:
Erik’s flavor
-----------
1 caramel
2 vanilla
3 pepermint
4 raspberry
5 plain
Choose your flavor: 4
Enter number 1, 2 or 3!
Choose your flavor:
"Tại sao lại thế?" Cậu hỏi anh Simon.
"Chương trình của em hoạt động chính xác như em đã
viết." Simon đáp. Tất nhiên, anh biết vấn đề nằm ở đâu.
"Em đã viết điều kiện của em như thế nào?" anh ấy hỏi.
Erik nói: "Nếu đáp án là 1, 2 hoặc 3. A ha, hiểu rồi! Mình
nhập '4' nên chương trình tưởng có sai lầm! Cần sửa thế
nào bây giờ ạ?"
“Có vẻ như chúng ta cần một danh sách các câu trả lời
hợp lệ cho mỗi danh sách thực đơn,” Simon nói. "Em có
thể chuyển nó sang đối số khác. Nhưng anh cho là em
đã đủ hiểu biết để cho một giải pháp tốt hơn."
"Cái gì ạ?" Erik hỏi lại. "Lại là vòng lặp một cái gì đó phải
không ạ?"
“Không chỉ vậy thôi đâu” Simon trả lời. "Chúng ta cũng
sẽ học điều gì đó mới về danh sách - list. Ừm, anh thấy
rằng em đã chán ngấy những bài giảng này rồi, nào hãy
cùng nhau kết thúc luôn trong hôm nay. Nó sẽ lại giúp
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

chương trình của em hoạt động bình thường trở lại –


thật đáng giá phải không nào?" Anh nháy mắt với chú
em.
Erik đang thấy oải lắm, mà cái bug menu về flavor thực
sự khiến cậu khó chịu và đang muốn sửa ngay tức khắc
(mà đúng là cậu ấy đã học được nhiều từ các bug lỗi!).
"Rồi rồi," cậu thở dài, "Nào cùng nhau sửa nó đi. Anh
muốn nói gì với em về danh sách?"
“Hãy nhìn vào khối điều kiện nè” Simon nói. "Em đang
sử dụng phép kiểm tra 'if-else' đơn giản, kiểm tra đầu
vào liệu có phù hợp với ba giá trị hợp lệ: 1, 2 và 3. Nhưng
nếu danh sách các item của em dài hơn, chẳng hạn như
20 mục thì sao giờ? Khối 'if-else' của em sẽ dài lòng
thòng. Python có một cách khác nữa. Chúng ta có thể
check có bao nhiêu item ở trong list danh sách. Hiện tại
chúng ta đang làm là kiểm tra liệu câu trả lời nhận từ
người dùng có nằm trong danh sách định trước là 1, 2,
3. Anh sẽ biểu diễn cách mới cho menu đầu tiên nhé."
Simon lấy bàn phím của Erik và sửa đoạn code if choice
== … trong hàm thành ra như hình bên dưới:

while True:
choice=input(prompt)
if choice in [‘1’, ’2’, ‘3’]:
answer=choices[int(choice)-1]
break
else:
print(“Enter number 1, 2 or 3!”)
answer=’’

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chỗ này cần giải thích một chút" anh nói. "Nhìn nè,
người dùng nhập một chuỗi có thể là '1' cũng có thể là
'42'. Chúng ta kiểm tra xem chuỗi này có nằm trong
danh sách các câu trả lời được phép hay không, tức là 1,
2, 3. Nếu nó không có trong danh sách, thì chúng ta in
thông báo lỗi và tiếp tục với vòng lặp. Nếu nó nằm trong
danh sách các câu trả lời được phép, thì chúng ta chuyển
đổi nó và chọn item đó từ danh sách menu."
“Vâng, em hiểu rồi” Erik nói. "Thế còn lỗi ở menu thứ
hai mà em gặp thì xử lý sao? Nó không cho em chọn số
4 vì nó không có trong điều kiện if của em. Với cách sửa
của anh vừa xong, em vẫn gặp vấn đề tương tự. Em có
năm flavor, vì vậy em cần một list danh sách các câu trả
lời khác ở đây, có phải thế không ạ?"
"Câu hỏi hay lắm!" Simon đáp. "Anh vừa định tự đưa ra
câu hỏi đấy. Đúng, em nói đúng. Mỗi danh sách thực đơn
nên có danh sách các câu trả lời được phép của riêng nó.
Chẳng phải là vấn đề lớn đâu; luôn xây dựng được một
list trả lời khi chúng ta biết danh sách thực đơn của
mình có gì. Để anh viết nó trước rồi sẽ giải thích từng
bước một." Simon đã thêm ngay các dòng vào trước
khối if mà anh ấy gõ trước đó:

while True:
choice=input(prompt)
allowed_answers=[]
for a in range(1, len(choices)+1) :
allowed_answers.append(str(a))
if choice in allowed_answers :
answer=choices[int(choice)-1]

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

break
else:
print(“Enter number 1, 2 or 3!”)
answer=’’

"Đầu tiên (xem nhãn 1), chúng ta tạo một list trống cho
các câu trả lời được phép. Sau đó (nhãn 2), chúng ta đo
độ dài của danh sách menu bằng hàm len(). Kết quả với
đồ uống sẽ là ba và với hương vị sẽ là năm. Sau đó,
chúng ta sử dụng hàm range() để tạo một dãy số từ 1
đến số chiều dài của menu. Đối với đồ uống, chuỗi sẽ là
1, 2, 3. Đối với hương vị sẽ là 1, 2 , 3, 4, 5. Em hiểu chưa.
Chỉ cần lưu ý rằng trong hàm range() chúng ta không
đếm được phần tử cuối cùng, coi như phần tử cuối cùng
không được bao gồm trong dãy. Đó là lý do tại sao chúng
ta phải thêm một vào độ dài của menu như thế này:"
len(choices)+1
"Và cuối cùng trong vòng lặp này (nhãn 3), chúng ta
chuyển đổi từng số trong dãy thành chuỗi và thêm số
đó vào vị trí cuối của list tên là allowed_answers. Hàm
này được gọi là append()." Simon giải thích một hồi rồi
lại nói thêm: "Ừm, lần đầu tiên nó hơi phức tạp, mà hãy
gắng tự mình đọc code Python đoạn này rồi em sẽ hiểu
nó như thể nó là tiếng Anh bình thường thôi."
"Bây giờ chúng ta phải thay đổi danh sách lấy giá trị sẵn
với 1, 2, 3 thành danh sách các câu trả lời được phép
allowed_answers vừa được tạo ra"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon sửa code xong. Anh ngắm nghía đoạn code rồi vỗ
trán: "Ồ, mình biết ngay mà!"
"Gì thế anh?" Erik nghĩ rằng công việc đã hoàn thành rồi,
mà có vẻ như lại có một cái gì đó khác xảy ra.
“Chúng ta cũng cần thay đổi dòng thông báo nữa,”
Simon nói. "Vì hiện giờ hàm của chúng ta có thể chấp
nhận danh sách menu có độ dài bất kỳ, nên chúng ta nên
nói với người dùng những điều như: 'Hãy nhập số từ 1
đến 6' hoặc 'từ 1 đến 12', theo độ dài của menu. Hãy nhớ
cách chúng ta lấy độ dài của một danh sách?"
"Dùng hàm len() ạ?" Erik hỏi.
"Đúng rồi!" Simon đáp, rồi thực hiện thay đổi cuối cùng
trong hàm. Bây giờ nó trông như thế này:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
while True:
choice=input(prompt)
allowed_answers=[]
for a in range(1, len(choices)+1) :
allowed_answers.append(str(a))
if choice in allowed_answers :
answer=choices[int(choice)-1]
break
else:
print(“Enter number from 1 to”, len(choices)”)
answer=’’
return answer

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Thêm danh sách allowed_answers


Thêm danh sách các câu trả lời được phép
allowed_answers vào hàm. Kiểm tra xem nó có cho
phép bạn sử dụng các list có độ dài khác nhau hay
không.
"Bây giờ chúng ta được bảo vệ khỏi lỗi do người dùng
rồi!" Simon nói. "Hãy thử và xem nó hoạt động thế nào
đi em!"
Erik chạy lại chương trình rồi nhập '42', 'coffee',
'weryiuryt587456' mà chương trình không xuất hiện
lỗi tồi tệ như trước. Mỗi lần chạy, máy cho lời nhắc nhở
cậu nên chọn một con số và con số ấy cần nằm trong
khoảng từ 1 đến 3 hoặc 5, tùy thuộc vào từng menu.
"Đây mới tuyệt vời nè! Nó hoạt động và nó không có
lỗi!" Erik thực sự vui lắm. Cậu ấy đã tạo ra một chương
trình mạnh mẽ tới thế.
“Thêm một điều nữa” Simon nói. "Anh hứa, cái này sẽ
thực sự-thực sự là cuối cùng cho ngày hôm nay!"
“Không sao anh” Erik đáp. Cậu bắt đầu thích cái thứ lập
trình này rồi. Cậu thích rằng chương trình của cậu ấy
bây giờ trông giống một chương trình thực tế và nó đã
chạy ngon lành! Kể cả nó chưa phải là một ứng dụng
trực tuyến hay ứng dụng di động, nó vẫn đang làm việc
như chương trình trong cửa hàng. Erik tưởng tượng
rằng cậu đang gõ lệnh đặt hàng tới quán cà phê yêu
thích, gọi đồ uống và sau đó đến lấy chúng.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon nói, "Chương trình của em bây giờ không cho


phép anh nhập bất cứ thứ gì ngoại trừ các số từ 1 đến 3
hoặc 5. Nhưng nếu anh muốn bỏ qua một món thì sao?
Ví như anh không muốn có tý topping nào trên đồ uống
ấy?"
"Trong menu hương vị, em đã có 'plain', có nghĩa là
'không có hương vị'. Anh có thể thêm thứ tương tự vào
toppings mà" Erik trả lời.
"Làm thế cũng được," Simon nói. "Nhưng nhìn chung
với mọi menu, em nên cung cấp cho người dùng một lựa
chọn thoát khỏi menu. Thông thường, người ta thấy
thông báo như này 'Nhấp X để thoát khỏi menu này'.
Anh nghĩ chúng ta cũng nên thêm dòng đó vào hàm."
"Chúng ta làm như thế nào?" Erik hỏi. Cậu suy nghĩ một
chút và bảo: "Em biết rồi! Chúng ta sẽ thêm 'X' vào list
của allowed answers! Liệu em nói có đúng không?"
"Chuẩn luôn!" Simon rất vui khi thấy em mình có tiến
bộ nhanh. "Hãy nhớ rằng chúng ta đã sử dụng hàm được
gọi là append() để thêm các item vào list danh sách?
Chúng ta có thể sử dụng nó chỗ này, ngay sau khi hoàn
tất việc thêm các số vào allowed_answers."
“Để em thử luôn” Erik nói và bắt đầu gõ.
“Hay lắm, làm tới luôn” Simon khuyến khích cậu em.
"Chỉ cần đảm bảo rằng em thêm nó sau vòng lặp for là
được. Tốt hơn là thêm một dòng trống sau nó; Em sẽ

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

thấy rằng bằng cách này nó không phải là một phần của
vòng lặp."
Đây là phiên bản mới cho hàm menu của Erik:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
while True:
choice=input(prompt)
allowed_answers=[]
for a in range(1, len(choices)+1) :
allowed_answers.append(str(a))
allowed_answers.append(‘X’)
if choice in allowed_answers :
answer=choices[int(choice)-1]
break
else:
print(“Enter number from 1 to”, len(choices)”)
answer=’’
return answer
“Đẹp rồi” Simon nói. "Anh thêm luôn một chữ 'x'
thường, bởi vì hầu hết mọi người sẽ gõ như thế. Nếu
người dùng gõ 'x' tất chúng ta nên làm gì bây giờ?"
"Có phải là sẽ thoát khỏi vòng lặp menu?" Erik nói.
"Đúng rồi! Nhưng chúng ta sẽ trả về cái gì cho chương
trình chính? Thông thường, chúng ta trả về lựa chọn của
người dùng từ menu: cà phê hoặc sô cô la hoặc cái gì đó.
Nếu người dùng gõ 'x' tất thì sao? Chúng ta nên trả lại
cái gì?"
"Không có gì cả phải không ạ?" Erik đề xuất.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đúng, chúng ta chỉ trả về một chuỗi rỗng," Simon nói.


"Nếu người dùng gõ 'x' tất, em chỉ đưa vào answer một
chuỗi trống như thế này: ''Trả về câu trả lời giống như
người dùng trả về câu trả lời nếu câu trả lời có trong
menu."
Simon tiếp tục: "Điều quan trọng: em nên thực hiện việc
check kiểm tra đó trước khi chuyển nó thành định dạng
số, rồi sau đó em kiểm tra xem nó có nằm trong danh
sách allowed_answers hay không. Em đã hiểu cần đặt
việc check này ở chỗ nào chưa?"
"Đây rồi, ngay sau dòng này: if choice in
allowed_answers."
"Tuyệt vời! Thêm luôn nó vào đi! Trong trường hợp này,
em sẽ có một câu lệnh if lồng nhau: câu if bên trong một
câu lệnh if khác. Trường hợp này khá phổ biến, đôi khi
em thấy ba cấp 'if' lồng nhau hoặc thậm chí còn nhiều
hơn nữa. Chỉ cần đảm bảo rằng em thụt lề chính xác. Đây
là cách Python cho máy tính biết phải làm gì với điều
kiện là đúng hoặc sai."
Erik sửa thêm đoạn code và cuối cùng đã nhận được
đoạn mã như hình:
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)
i = i+1
while True:
choice=input(prompt)
allowed_answers=[]
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

for a in range(1, len(choices)+1) :


allowed_answers.append(str(a))
allowed_answers.append(‘X’)
allowed_answers.append(‘x’)
if choice in allowed_answers :
if choice == ‘X’ or choice == ‘x’ :
answer= ’’
break
else
answer=choices[int(choice)-1]
break
else:
print(“Enter number from 1 to”, len(choices))
answer= ’’
return answer
LƯỢT CỦA BẠN: Thêm lựa chọn thoát khỏi menu
Thêm lựa chọn 'X' vào danh sách các câu trả lời
được phép – allowed_answer. Thêm vào câu lệnh 'if'
lồng nhau để kiểm tra. Kiểm tra xem chương trình
có hoạt động không. Nếu bạn nhập 'x' vào tất cả các
menu thì sao? Bạn sẽ nhận được đơn đặt hàng thế
nào trong trường hợp đó?
Cậu đã thử nghiệm chương trình bằng cách nhập 'x' vào
cả ba menu và nhận được những gì cậu ấy mong đợi:
Erik’s Menu
----------
1 chocolate
2 coffee
3 decaf
Choose your item: x
Erik’s flavor
-----------
1 caramel
2 vanilla
3 pepermint
4 raspberry
5 plain
Choose your flavor: x
Erik’s toppings
-------------
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

1 chocolate
2 cinnamon
3 caramel
Choose your topping: x
Here is your order:
Main product:
Flavor:
Topping:
Thank for your order!
"Một đơn đặt hàng rỗng tuếch!" Cậu thốt lên.
"Phải, chính xác là nó phải thế," Simon xác nhận. "Anh
thích chương trình của em" Anh nói tiếp. "Nó hoạt động
rồi—đó là phần đầu tiên và cũng là phần quan trọng
nhất. Chương trình thân thiện với người dùng, nó đưa
hướng dẫn cho người dùng về những việc cần làm—đó
là phần thứ hai. Chương trình kiểm tra đầu vào và
không cho phép người dùng nhập sai giá trị— đó là
phần thứ ba."
"Hãy cùng nhau tóm tắt ngắn gọn những gì em đã học
ngày hôm nay xem nào" Simon nói. "Cái đầu tiên là gì?"
"Đầu tiên là, anh tiếp tục phá hoại chương trình của
em!" Erik đáp lại như vậy. Lần này cậu không tức giận
lắm, vì cậu biết rằng cùng với Simon, họ đã sửa xong
chương trình. "Rồi anh nói với em rằng em phải luôn
nghĩ tới người dùng có thể sử dụng chương trình theo
cái cách tệ hại như thế nào."
“Phải rồi, đối phó với những người dùng cứng đầu
không muốn làm theo hướng dẫn là một phần công việc
của lập trình viên” Simon mỉm cười.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Sau đó, chúng ta đã viết một vòng lặp menu để chúng


ta kiểm tra những gì người dùng đã nhập và không cho
phép họ sử dụng các câu trả lời không được phép. Sau
đó, anh nói với em về hàm append() có tác dụng điền
thêm nội dung vào danh sách."
Erik nói tiếp "Sau đó, em đã viết các câu lệnh if lồng
nhau và bây giờ code của em trông giống như các
chương trình thực tế đang được chiếu trong phim."
Simon mỉm cười, "Tin anh đi, những gì họ chiếu trong
phim rất hiếm khi là chương trình thực. Nhưng em nói
đúng, chương trình của em ngày càng phức tạp hơn, nó
sử dụng các toán tử Python khác nhau, nhiều vòng lặp,
nhiều list danh sách."
"Tiếp theo chúng ta đã thêm tùy chọn 'x' vào menu và
bây giờ bất kỳ người dùng nào cũng có thể nhận được
đơn hàng trống rỗng!" Erik cười khúc khích.
“Đúng rồi, tại sao lại không nhỉ” Simon nói. "Em không
được ép buộc người dùng của mình cứ phải đặt hàng.
Em nên cung cấp cho họ lựa chọn hủy đơn hàng hoặc
thoát khỏi menu."
Simon nói tiếp "Chương trình của em đã thực sự tốt rồi.
Ngày mai anh sẽ đề nghị em ngừng làm lập trình viên
mà hãy trở thành quản lý quán cà phê."
“Không phải em đang là quản lý rồi sao?" Erik hỏi.
“Đúng, đúng là như thế,” Simon mỉm cười. "Bây giờ hãy
tưởng tượng thế này, em - người quản lý quán cà phê,
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

vừa nhận được một thành phần hương vị flavor mới cho
thức uống cà phê. Rồi em muốn thêm flavor đó vào thực
đơn. Ồ, cũng thêm đôi ba loại toppings mới nữa. Em sẽ
làm gì?"
“Em sẽ thêm những thứ đó vào danh sách topping,
không có gì to tát cả” Erik đáp.
"Đúng rồi, giả sử em chỉ là người quản lý chứ không phải
lập trình viên thì sao? Em không biết gì về lập trình, em
không biết Python, nhưng em muốn thêm mấy thứ
hương vị và topping đó vào thực đơn. Em, với tư cách là
một lập trình viên, cần cung cấp cho nhà quản lý biện
pháp thêm thứ gì đó vào menu một cách dễ dàng."
"Anh gợi ý cách làm đi?" Erik hỏi. Cậu ấy biết rằng
Simon đã có câu trả lời trong đầu rồi.
"Anh nghĩ chúng ta nên đặt thực đơn trong các tệp file
và đọc list danh sách từ các tệp file đó."
"Như kiểu tệp file Word phải không ạ?" Erik hỏi.
“Ừ, gần giống như vậy” Simon trả lời. "Chương trình của
em sẽ mở và đọc các tệp đó. Anh nghĩ cách dễ nhất là
mỗi menu có một tệp file. Một tệp file sẽ có tên tất cả đồ
uống, một tệp khác - là tên tất cả hương vị và tệp kia -
tất cả các loại topping. Sau đó, nhà quản lý sẽ chỉ chỉnh
sửa những tệp đó thay vì chỉnh sửa mã code Python.
Nghe có thấy thú vị không?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Vâng, thú vị thật” Erik trả lời. Cậu tự hỏi làm thế nào để
chương trình Python có thể mở các tệp giống như cách
mà Word thực hiện.
“Tuyệt vời” Simon thốt lên. "Đây là những gì chúng ta sẽ
làm vào ngày mai. Giờ thì hãy nghỉ ngơi đã."

4.2 Những điều mới mà bạn đã học được


ngày hôm nay

● Người dùng mắc lỗi


Bạn đã học được rằng người dùng không phải lúc nào
cũng làm theo hướng dẫn mà bạn đã cung cấp trong
chương trình. Bạn phải sẵn sàng cho các sai lầm và kiểm
tra đầu vào trước để tìm lỗi, tìm sai lầm, v.v.
● Thụt đầu dòng
Khi bạn tạo một khối trong Python (ví dụ như khối lệnh
while), bạn phải đảm bảo rằng tất cả code trong khối
được thụt vào, tức là được dịch chuyển sang bên phải.
● Cách thoát khỏi menu
Bạn cần cung cấp cho người dùng một cách để thoát
khỏi mỗi menu. Ví dụ: nếu họ không muốn gọi bất kỳ
loại topping nào hay là họ muốn bỏ qua menu đó.

4.3 Code cho chương này


Bạn có thể tìm thấy code cho chương này ở đây:
https://github.com/pavelanni/lets-talk-python-book/tree/main/ch04
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Làm việc với tệp file: Trong vai trò


quản lý cửa hàng

Chương này bao gồm


 Erik học những công tác một nhà quản lý quán
cà phê cần
 Erik đọc thực đơn từ các tập tin
 Erik viết hàm Python cá nhân thứ hai

“Hôm qua anh đã nói về một nhà quản lý quán cà phê,”


Erik bắt đầu buổi học với anh trai mình vào ngày hôm
sau. "Liệu có vấn đề gì với việc thay đổi thực đơn anh
nhỉ. Em quên mất rồi."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Ừ, anh nói là sẽ hợp lý nếu người quản lý quán cà phê


có thể thay đổi thực đơn mà không cần sửa code
Python,” Simon nói.
“Vâng, ý kiến này rất hay” Erik nói. "Không phải ai cũng
biết Python."
"Ý tưởng của anh là tạo các tệp chứa đoạn text đơn giản
cho mỗi menu – đặt tên lần lượt là drinks.txt, flavors.txt
và toppings.txt. Sau đó, chương trình của em đọc các tệp
đó và tạo list danh sách từ các món trong tệp."
"Tại sao anh lại đặt tên tất cả chúng đuôi .txt ạ?" Erik
hỏi. "Liệu chúng có nên là .docx để người quản lý dễ
dàng chỉnh sửa trong Microsoft Word không?"
“Ý kiến hay đấy” Simon nói. "Đúng là người quản lý có
thể quen thuộc Word hơn, nhưng trong trường hợp này,
chúng ta chỉ cần một tệp đoạn text thuần túy, không cần
phông chữ, không tiêu đề, không mục lục. Nó tương tự
như đoạn code Python của em - các tệp này không được
có gì ngoài các dòng text thuần túy và người quản lý nên
sử dụng trình soạn thảo text thuần túy khi làm việc với
chúng. Khi anh đặt tên cho các tệp có đuôi .txt, anh nói
với hệ điều hành - dù là Windows, macOS hay Linux -
rằng tệp này nên được mở với trình soạn thảo đoạn text
thuần túy chứ không phải trình xử lý text như Word.
Trong tất cả các hệ điều hành đó luôn có một trình soạn
thảo đoạn text có thể chỉnh sửa các tệp này. Mà em cũng
có thể cài đặt một ứng dụng khác cho việc chỉnh sửa text
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

này, giống như chúng ta đã làm với Mu Editor. Thêm


nữa, đối với Python, việc đọc từ file text thuần túy dễ
dàng hơn nhiều so với đọc từ file đuôi .docx."
"Chúng ta hãy cùng nhau tạo ra file này đi nào" Simon
nói tiếp. "Em có thể sử dụng Trình chỉnh sửa Mu để làm
đấy. Chỉ cần đừng quên thêm phần mở rộng .txt khi lưu
tệp lại. Nếu em không thêm đuôi thì nó sẽ tự động thêm
.py. Hãy tạo một tệp mới, nhập đồ uống vào, mỗi item
trên một dòng riêng và lưu nó với tên drink.txt. Sau đó,
hãy làm tương tự cho flavor và topping."
Erik bắt đầu gõ. Chỉ mất vài phút, cậu có ba tập tin.

LƯỢT CỦA BẠN: Tạo tập tin menu của cá nhân bạn
Tạo các file text đặt các item vào menu như Erik vừa
làm. Hãy chắc chắn rằng chúng là các file text thuần
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

túy. Hay lấy flavors và toppings yêu thích của bạn


vào thực đơn cá nhân.
"Giờ thì sao ạ?" Cậu hỏi anh trai.
"Bây giờ, hãy học cách làm việc với các file trong Python.
Hãy tạo một chương trình mới. Chúng ta sẽ thực hành
một chút và sau đó đoạn mã này sẽ được thêm vào
chương trình chính. Anh vẫn thường làm thế khi học
điều gì đó mới – ta cứ thử nghiệm cái mới trong một
chương trình đơn giản riêng biệt trước khi thêm vào
ứng dụng chính."
Simon tiếp tục giảng giải "Hãy tạo một tệp mới trong
trình chỉnh sửa editor và lưu nó với tên files.py."
Erik đã làm theo hướng dẫn nhiều lần rồi nên cậu chỉ
mất có vài giây.
“Làm việc với các tập tin là một chủ đề khó, vì vậy hãy
để anh bắt đầu với một sơ đồ” Simon nói.

"Khi em làm việc với một tệp trong máy tính, em sử


dụng tên file. Em yêu cầu chương trình soạn thảo của
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

mình mở một tệp có tên 'drinks.txt'. Sau đó, chương


trình soạn thảo của em sẽ đọc tệp và hiển thị cho em nội
dung của tệp đó. Tiếp theo, em chỉnh sửa tệp và lưu nó
có nghĩa là em ghi tệp trên đĩa máy tính. Em hiểu cả đấy
chứ?" Simon hỏi.
“Vâng,” Erik nói. "Nhưng đĩa chỉ được sử dụng trong các
máy tính cũ xì thôi. Trong máy tính của em, nó được gọi
là ổ SSD và thế giới này làm gì còn cái nào là đĩa nữa.
Cậu bạn Alex đã nói với em như thế."
"Em hoàn toàn đúng!" Simon rất vui khi em trai mình
nói thế. "Đúng, bây giờ hầu hết các máy tính đều là SSD
và đương nhiên, nó không phải là đĩa và nó không quay.
Nhân tiện đã nhắc tới, cậu bạn Alex của em có muốn
tham gia cùng chúng ta không? Có vẻ như em ấy cũng
quan tâm đến máy tính. Liệu em ấy có muốn học lập
trình không?"
“Em sẽ hỏi bạn ấy,” Erik nói. "Mà hãy quay lại tập tin của
em đi. Em thấy rằng anh đã viết 'máy tính' và 'Python' ở
trên đầu hình. Điều đó có nghĩa là gì ạ?"
"Điều đó có nghĩa là," Simon bắt đầu giải thích, "rằng
trong Python nếu em muốn làm việc với một tệp, em
phải tạo một object đặc biệt thường được gọi là file
handle. Em sử dụng object này để đọc và ghi tệp. Em
dùng một hàm gọi là open() để tạo một đối tượng như
vậy. Em gõ hàm open() và em truyền tên file làm đối số.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Trong trường hợp của chúng ta, nó sẽ là


open("drinks.txt"). Hàm trả về file handle mà em đã đặt
vào một biến. Trong trường hợp này, biến được gọi là f,
tuy nhiên em có thể sử dụng bất kỳ tên nào thay thế."
"Tại sao lại phức tạp như vậy ạ?" Erik hỏi. "Tại sao
chúng ta không thể sử dụng tên file?"
"Ừ, lần đầu tiên có vẻ hơi phức tạp. Lý do là vì tên file
chỉ là một chuỗi, nhớ không em? Khi chúng ta muốn đọc
tệp, chúng ta muốn đọc từ tệp có tên đó chứ không phải
đọc chuỗi. Tên file và bản thân file là hai khái niệm khác
nhau. Khi chúng ta sử dụng hàm open(), chúng ta tạo
một kết nối giữa tên file và bản thân tệp đó. Chúng ta
nói với Python:
'Vui lòng tìm tệp có tên drink.txt bên trong máy tính và
sử dụng nó như là một file.' Tạm thời đừng lo lắng quá
nhiều về nó. Đôi khi cách tốt nhất để hiểu một điều là lạ
là cứ dùng nó luôn."
“Được ạ,” Erik nói. Cậu ấy vẫn còn hơi bối rối về tất cả
những điều vừa xong nhưng cậu muốn xem cách
chương trình đọc các menu từ các file text vừa được tạo
ra.
"Bây giờ hãy viết một chương trình Python đơn giản để
làm việc với các tệp," Simon nói. "Bây giờ hãy chuyển
đến chương trình files.py em đang mở trên trình editor.”

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Hãy nhìn sơ đồ của anh: em phải gõ hàm open(), truyền


tên file chẳng hạn như 'drinks.txt' và lưu kết quả vào
biến f. Liệu em viết được nó không?"

“Để em làm thử” Erik nói và gõ câu lệnh.


f = open(“drinks.txt”)
"Tốt lắm!" Simon nói. "Bây giờ em đã có một tệp được
đặt tên và em có thể đọc nó rồi. Để làm điều đó, gõ một
phương thức có tên là read(). Các phương thức nhìn
chung hoạt động rất giống với các hàm, nhưng các
phương thức được áp dụng cho object [đối tượng cụ
thể]. Chúng ta sẽ nói về các đối tượng sau nhưng bây giờ
tất cả những gì em cần biết là để gọi một phương thức
cho một đối tượng, em sử dụng tên của đối tượng, rồi
em đặt một dấu chấm và sau đó là tên phương thức cùng
với dấu ngoặc đơn, tương tự như gọi một hàm. Làm như
thế này: f.read(). Các phương thức - method cũng có thể
trả về một cái gì đó, tương tự như các hàm. Vì vậy, em
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

phải tìm chỗ lưu trữ kết quả. Đố em phương thức read()
này sẽ trả về kết quả gì khi em gọi nó ra?"
“Em nghĩ là nội dung bên trong tập tin” Erik trả lời.
"Chuẩn luôn!" Simon nói. "Lưu nó trong một biến có tên
là drinks rồi thử in nó ra xem nào."
Erik gõ lệnh như sau:
f = open(“drinks.txt”)
drinks = f.read()
print(drinks)
"Bây giờ hãy thử chạy nó đi" Simon gợi ý.
Erik kích Run và nhận được đầu ra.
coffee
chocolate
decaf

>>>
LƯỢT CỦA BẠN: Đọc file [Đặt file txt cùng địa chỉ với
file python]
Viết một chương trình ngắn giống thế và thử đọc từ
tệp 'drinks.txt'. Hãy chắc chắn rằng bạn sẽ in được
toàn bộ nội dung của tệp.
"Nó hoạt động rồi!" Erik rất vui mừng. Chương trình
Python của cậu đã mở một tệp, đọc nó và in nó ra! "Giờ
thì em đã biết cách in các menu từ Python! Hãy để em
viết tương tự cho hai tệp còn lại!"
“Ừ” Simon nói. "Nhưng đó không phải chính xác những
gì chúng ta muốn."
"Sao cơ?" Erik không hiểu.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Hãy nhớ rằng, trong chương trình này, em không chỉ in


ra các menu mà còn cho phép người dùng chọn từ đấy
rồi sau đó em tìm item trong danh sách, có phải thế
không?"
"Vâng, nhưng dường như đây không phải là một danh
sách ạ? Nó giông giống một danh sách thôi." Erik hỏi.
"Nó giông giống một danh sách, nhưng nó không phải là
một danh sách. Đó là một chuỗi," Simon nói. "Khi em gõ
phương thức read(), em đã sao chép toàn bộ nội dung
của tệp vào một biến gọi là drinks. Vì vậy, biến này chỉ
là một chuỗi lớn thôi. Nếu không tin, em thử test nó
ngay đi. Em có thấy ba dấu ngoặc nhọn trong cửa sổ đầu
ra không? Em có thể nhập bất kỳ lệnh Python nào tại
đây để tiếp tục làm việc với chương trình, giống như
cách chúng ta đã làm với REPL, em còn nhớ không? Hãy
nhập vào đây: type(drinks) rồi em sẽ thấy định dạng
đầu ra type của biến này." Erik kiểm tra, cậu thấy kết
quả như hình:
>>> type(drinks)
<class’str’>
>>>
"Em thấy chưa, Python nói nó là một dạng string –
chuỗi" Simon thốt lên. "Còn chúng ta cần một list – danh
sách."
"Chúng ta nên làm gì ạ?" Erik hỏi.
"May mắn thay, các nhà phát triển Python biết rằng
chúng ta có thể cần điều này, họ đã tạo một phương
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

thức khác cho đối tượng tệp. Nó được gọi là readlines().


Hãy thử thay đổi read() thành readlines() rồi xem điều
gì sẽ xảy ra. Đừng quên nhấn vào Dừng – Stop - trước
khi chạy Run lại chương trình đấy."
Erik sửa lại chương trình như sau:
f = open(“drinks.txt”)
drinks = f.readlines()
print(drinks)
Anh ấy bấm Dừng - Stop rồi Run lại và nhận được kết
quả như sau:
[‘coffee\n’, ‘chocolate\n’, ‘decaf\n’]
>>>
“Thử kiểm tra lại type của nó đi em” Simon gợi ý.
Erik chuyển sang cửa sổ đầu ra và gõ:
>>> type(drinks)
<class’list’>
>>>
LƯỢT CỦA BẠN: Kiểm tra các loại định dạng trong
Python
Lặp lại các kiểm tra mà Erik vừa làm. Bạn có thấy sự
khác biệt giữa một chuỗi string và một danh sách
list không?
"Đó là một danh sách!" Cậu hô. "Thế còn những ký tự
gạch chéo đó là gì ạ? Em làm gì có chúng trong file đồ
uống đâu.”
[Ký tự xuống dòng là một ký tự đơn (thường là 8 bit).
Nó được thể hiện trong nguồn chương trình (ở dạng ký
tự chữ hoặc chuỗi ký tự) theo trình tự hai ký tự \n. Ký

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

tự xuống dòng '\n' là hằng số ký tự đại diện cho một ký


tự đơn.]
"Em không nhìn thấy chúng trong tệp thật nhưng chúng
được lưu trữ như thế. Đây là những ký tự vô hình. Khi
em nhìn thấy dấu gạch chéo kèm chữ n này, đó là một
ký tự đơn được gọi là ký tự 'xuống dòng'. Nó cho máy
tính biết rằng nó nên in item tiếp theo ở đầu dòng mới.
Nếu không có nó, tất cả đồ uống của em sẽ được in dính
vào nhau như thế này: coffeechocolatedecaf. Liệu em có
muốn như thế không?" Simon mỉm cười.
"Dĩ nhiên là không rồi!" Erik trả lời. "Nhưng chúng ta
không cần chúng trong danh sách, phải không ạ? Em
nghĩ danh sách menu phải giống trong chương trình
chính của em ấy, có phải như thế không?"
"Em hoàn toàn đúng. Lại một lần nữa, các nhà phát triển
Python đã tạo ra một phương thức rất hữu ích cho việc
đó. Nó được gọi là strip() và nó loại bỏ các ký tự vô hình
khỏi cả hai đầu của chuỗi. Chúng ta chỉ cần áp dụng nó
cho mọi item trong list. Em nghĩ xem chúng ta nên dùng
cái gì ở đây?"
"Một vòng lặp đúng không ạ?" Erik dè dặt đáp.
"Đúng rồi, một vòng lặp!" Simon nói. "Chúng ta sẽ duyệt
qua danh sách và xóa các ký tự xuống dòng bằng
phương thức strip()."
Simon dừng lại một lúc để suy nghĩ. Sau đó, anh tiếp tục
giảng bài "Có một vài cách để làm điều đó. Có cách ngắn
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

hơn nhưng khó hiểu hơn. Nào thì dùng cách dễ đọc và
dễ làm trước đã. Thực ra đây là một quy tắc tốt trong
lập trình: khi cần lựa chọn giữa các cách làm khác nhau,
hãy luôn chọn cách dễ đọc và dễ làm theo. Nếu ai đó
đang đọc code của em, họ sẽ cảm ơn thái độ của em.
Thậm chí là cả chính em nữa - nếu em đọc lại code của
bản thân sau chỉ khoảng ba tháng thôi."
Anh nhanh chóng vẽ sơ đồ.

"Chúng ta sẽ sử dụng một danh sách tạm thời để đọc từ


tệp. Sau đó, chúng ta sẽ duyệt qua danh sách tạm thời
đó, chuyển đổi từng item và nối nó thành danh sách
mới. Rồi list mới đó chúng ta sẽ gọi là drinks. Sau đó,
chúng ta sẽ lặp lại tương tự cho flavors và toppings.
Chúng ta có thể sử dụng cùng một biến tạm thời cho tất
cả chúng. Để anh giúp em một tay nhé" Thế là Simon bắt
đầu gõ vào chương trình của Erik. Đây là kết quả sau khi
anh ấy gõ xong mấy câu lệnh.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

f = open(“drinks.txt”)
temp = f.readlines()
drinks = []
for item in temp:
new_item = item.strip()
drinks.append(new_item)
print(drinks)
Anh ấy click Run và kết quả như sau:
[‘coffee’, ‘chocolate’, ‘decaf’]
>>>
LƯỢT CỦA BẠN: Xóa các ký tự xuống dòng
Xóa các ký tự xuống dòng ra khỏi các item trong
menu bằng phương thức strip().
[Lời người dịch: Sự khác nhau giữa Method – phương
thức và Function - hàm trong Python:
 Cả Method và Function đều khá giống
nhau trong cách hoạt động.
 Điểm khác nhau chính giữa Method và
Function chính là khái niệm Class và Object.
Function có thể được gọi bởi
tên trong khi method phải gọi thông qua class
hoặc đối tượng.]
"Có vẻ tốt hơn rồi nhỉ?" Anh hỏi Erik. "Bây giờ hãy tiếp
tục và làm điều tương tự cho các tệp menu khác."
Erik bắt tay vào gõ lệnh và khi cậu ấy gần như đã hoàn
thành xong với tệp flavor.txt, cậu hét lên, "Thong thả
nào! Em đang lặp lại chính mình kìa! Anh đã nói rằng
không nên lặp lại chính mình mà."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon mỉm cười. Anh rất vui vì cậu em nắm bắt khái
niệm này nhanh chóng. "Chúng ta phải làm gì để không
lặp lại?" Anh hỏi.
"Viết hàm ạ?" Erik hỏi
"Đúng, đúng cực kỳ! Hãy nhìn vào đoạn code này: cái gì
giống nhau và cái gì đang thay đổi? Đối số là cái nào và
hàm này sẽ trả về cái gì?"
Erik buột miệng nói suy nghĩ thành tiếng “Em mở các
tệp khác nhau, vì vậy tên file phải là một đối số, có phải
không ạ?"
"Chuẩn!" Simon xác nhận. "Em muốn trả về cái gì?"
"Em nghĩ rằng sẽ trả về danh sách với các lựa chọn trong
menu. Tất nhiên là sau khi chúng ta xóa các ký tự xuống
dòng. Nhưng em nên gọi danh sách này như thế nào ạ?"
"Em có thể gọi nó theo bất kỳ cách nào em muốn vì nó
không thể nhìn thấy từ bên ngoài. Gọi nó là kết quả -
result chẳng hạn. Sau đó, em viết return result ở cuối
hàm. Khi em gọi hàm danh sách list đã được gán cho
biến result của chương trình, giống hệt như drinks hoặc
flavors phụ thuộc vào file em đọc. Bên trong hàm, biến
sẽ luôn được gọi là result, nhưng trong chương trình
chính bên ngoài hàm, em có thể gán kết quả cho bất kỳ
biến nào."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tiếp tục viết hàm nào!" Simon khuyến khích cậu em.
“Còn nhớ cách làm không em? Bắt đầu với def. Ta đặt
một cái tên cho hàm như là read_menu chẳng hạn;
chuyển filename làm đối số; rồi sao chép code chúng ta
vừa viết được."
"Được rồi, để em làm xem nào" Erik nói và bắt đầu viết
hàm Python cá nhân thứ hai.
Simon đã giúp cậu em một tay và đây là những gì cả hai
anh em đã viết cùng nhau.
Listing 5.4 file.py
def read_menu(filename):
f = open(filename)
temp = f.readlines()
result = []
for item in temp:
new_item = item.strip()
result.append(new_item)
return result
drinks = read_menu(“drinks.txt”)
print(drinks)
flavors = read_menu(“flavors.txt”)
print(flavors)
toppings = read_menu(“toppings.txt”)
print(toppings)

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik lưu tệp và kích Run. Tất nhiên, cậu nhận được ngay
kết quả như mong đợi.
[‘coffee’, ‘chocolate’, ‘decaf’]
[‘caramel’, ‘vanilla’, ‘peppermint’, ‘raspberry’, ‘plain’]
[‘chocolate’, ‘cinnamon’, ‘caramel’]
>>>
LƯỢT CỦA BẠN: Tạo hàm read_menu
Tạo hàm read_menu giống như vừa rồi Erik đã làm.
Bạn hãy chắc chắn rằng không có lỗi đánh máy phần
tên file. Bạn nhầm tên file thì điều gì sẽ xảy ra? Hãy
thử thay đổi tên file và xem Python gây ra lỗi gì cho
bạn. Đừng quên sửa tên file để chương trình của
bạn hoạt động trở lại.
"Đó là hàm thứ hai của em và nó hoạt động ngon rồi!"
Cậu tự hào nói với anh trai.
"Đúng, em đang xây dựng thư viện hàm của riêng mình
đấy, thật tuyệt vời!" Simon nói. "Bây giờ, hãy sao chép
hàm mới của em vào chương trình chính. Đừng sao chép
các dòng print() - chúng ta chỉ sử dụng chúng để thử
nghiệm mà thôi. Anh nghĩ cái tệp này ta đặt cho nó cái
tên là menu_function.py, được không em?"
“Vâng,” Erik đáp. "Mà em nên đặt hàm ở đâu trong tệp?
Nên trên đầu hay xuống cuối ạ?"
"Quy tắc trong Python là em nên xác định hàm của mình
trước khi bắt đầu sử dụng. Vì vậy mà thông thường tất
cả các hàm đều được đặt ở đầu file, trước chương trình
chính. Em đặt nó ngay sau hàm đầu tiên cũng được."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Xong phim,” Cậu Erik mồm nói tay làm. Đây là đoạn
chương trình vừa xong:
Listing 5.5 file.py
def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):
...
# this function didn’t change
...
return result
def read_menu(filename):
f = open(filename)
temp = f.readlines()
result = []
for item in temp:
new_item = item.strip()
result.append(new_item)
return result
drinks = read_menu(“drinks.txt”)
flavors = read_menu(“flavors.txt”)
toppings = read_menu(“toppings.txt”)
drink = menu(drinks)
flavor = menu(flavors, “Erik’s flavors”, “Choose your flavor: “)
topping = menu(toppings, “Erik’s toppings”, “Choose your topping: “)
print(“Here is your order: “)
print(“Main product: “, drink)
print(“Flavor: “, flavor)
print(“Topping: “, topping)
print(“Thanks for your order!“)
LƯỢT CỦA BẠN: Hãy sao chép hàm vừa làm xong
vào chương trình chính.
Sao chép hàm read_menu() mới vào chương trình
chính và dùng thử ngay.
Cậu ấy đã thử nghiệm chương trình và nó hoạt động
chính xác như trước đây!

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Cái này tốt đấy,” Simon nhận xét. "Bây giờ hãy thử
thêm thứ gì đó vào tệp toppings chẳng hạn. Rồi ta xem
nó có thay đổi menu không."
Erik mở tệp toppings.txt và thêm 'vanilla powder' vào
cuối tệp, xong rồi lưu lại. Cậu chạy lại chương trình và
thực sự có dòng bổ sung ở menu cuối cùng: 4 vanilla
powder!
LƯỢT CỦA BẠN: Thêm item nữa
Thêm một item mới vào một trong các menu. Thay
đổi một trong các item. Đừng quên lưu các tệp menu
sau khi đã thay đổi chúng. Hãy kiểm tra xem
chương trình của bạn có in các menu được cập nhật
vừa xong hay không.
"Chương trình tốt rồi, em thích lắm!" Cậu thốt lên. "Bây
giờ bất kỳ ai biết chỉnh sửa file text đều có thể thay đổi
menu! Từ từ nào..." Cậu nảy ra một ý tưởng. "Này, em sẽ
đặt bất cứ thứ gì vào những thực đơn này! Kem, bánh
mì sandwich hoặc... ngon rồi! Em phải nói với bạn Alex
về cái này mới được – Bạn ấy thích những khối LEGO
nho nhỏ. Có lẽ nó có thể dùng chương trình này để trao
đổi hình ảnh với bạn bè!"
"Được đấy!" Simon nói. "Anh rất vui vì em có nhiều ý
tưởng về cách sử dụng chương trình, điều này vui lắm
đấy! Anh cũng có một số ý tưởng nhưng tốt hơn ngày
mai chúng ta mới bàn tới chủ đề này. Thêm nữa, ngày
mai chúng ta sẽ tạo menu chính."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Ý anh là gì?"


"Em thấy đấy, bây giờ mỗi khi em muốn nhận một đơn
đặt hàng em phải khởi động chương trình của mình. Em
nhận đơn hàng rồi in ra sau đó chương trình sẽ kết thúc.
Nếu chương trình quay trở lại luôn màn hỏi tên khách
hàng tiếp theo thì sẽ tốt hơn nhiều."
“Phải, phải” Erik đồng ý. "Cũng giống như ở kiosk đặt
hàng ấy ạ, nhấn 'Done - Xong' thì nó sẽ chạy lại màn hình
đầu tiên có câu 'Chào mừng đến với cửa hàng của chúng
tôi'. Vâng, chúng ta cùng làm luôn nào!"
"Em hãy tóm tắt lại tiến trình của ngày hôm nay nào"
Simon yêu cầu. "Hôm nay chúng ta đã làm gì?"
"Đầu tiên, anh nói rằng người quản lý quán cà phê sẽ
muốn chỉnh sửa thực đơn trong các file. Sau đó, em đã
viết ba file thực đơn cho drinks, flavors và toppings."
"Rất tốt, tiếp theo là gì?"
"Sau đó, em mở và đọc các tệp. Em duyệt từng dòng
nhưng xuất hiện ký tự ‘\n’ kỳ lạ. Thế là chúng ta sử dụng
phương thức strip() để xóa chúng đi."
“Tốt!” Simon nói. "Thế em có nhớ những gì anh đã nói
với em về object không?"
"Lơ mơ lắm ạ. Anh nói tệp file là một đối tượng - object
trong Python và tên object không trùng với tên file. Anh
cũng đề cập các hàm cho đối tượng được gọi là 'phương
thức - method'."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đúng, đều đúng hết" Simon nói. "Object là một chủ đề


khó, chúng ta sẽ nói thêm về nó sau. Bây giờ chúng ta
chỉ sử dụng object và các phương thức - method , nhưng
chúng ta sẽ học thêm về chúng sau. Sau này chúng ta
cũng sẽ tạo các đối tượng và phương thức cá nhân mình
- giống như chúng ta đã làm với hàm."
"Vâng!" Erik hô to. "Em đã nhớ lời nhắc nhở – thế là em
viết hàm Python cá nhân thứ hai! Cuối cùng nó đã hoạt
động ngon lành!"
"Quả đúng là thế! Giờ đây em đang trở thành một lập
trình viên chuẩn rồi!" Simon nói và mỉm cười. "Giờ thì
nghỉ ngơi đã. Ngày mai chúng ta sẽ làm cho chương
trình của em tốt hơn nữa!"

5.1 Những điều mới mà bạn đã học được


ngày hôm nay

● Ý nghĩa của việc mở một tệp


Bạn đã học được sự khác biệt giữa tên file và file xử lý
tệp bên trong chương trình.
● \n là gì và cách xóa nó khỏi chuỗi
Bạn đã biết rằng biểu tượng \n có nghĩa là "bắt đầu một
dòng mới". Chúng ta không cần nó trong các item menu
nên ta sử dụng hàm strip() để xóa nó đi.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

● Thứ trả về từ một hàm được gán cho một biến trong
chương trình chính
Bạn đã biết rằng biến bên trong hàm không hiển thị
trong chương trình chính. Để truyền giá trị của nó,
chúng ta phải trả về biến từ hàm và gán giá trị của nó
cho một biến khác trong chương trình chính.

5.2 Code cho chương này

Bạn có thể tìm thấy code cho chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch05

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Menu chính: Khách hàng tiếp theo!

Chương này bao gồm


 Erik tạo menu chính để phục vụ nhiều khách
hàng
 Erik tìm hiểu về từ điển Python
 Simon giải thích cách tiếp cận cách phát triển
'từ trên xuống'

"Em còn nhớ chúng ta đã quyết định cần phải tạo menu
chính không?" Simon hỏi Erik.
"Đương nhiên nhớ chứ ạ, anh nói nếu em muốn sử dụng
chương trình này để phục vụ nhiều khách hàng, em phải
quay lại thực đơn cho từng khách hàng. Hỏi tên và hỏi
từng người muốn gọi món gì."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chính xác rồi!" Simon nói. "Thế em sử dụng cái gì để


làm được điều đó?"
"Vòng lặp, có lẽ vậy? Giống như chúng ta đã làm với các
menu. Lặp lại cho đến khi khách hàng nhập đúng con số
hoặc nhập 'X'."
"Em hoàn toàn đúng!" Simon thực sự vui mừng vì em
trai của mình đã nắm bắt được ý tưởng lập trình này
một cách nhanh chóng. "Chúng ta sẽ hỏi khách hàng tên,
giống như trong chương trình đầu tiên, em có nhớ
không? Sau đó, chúng ta sẽ nhận đơn đặt hàng với tất cả
flavor and toppings."
"Vâng," Erik tiếp tục, "Rồi chúng ta sẽ hỏi họ: Đặt hàng -
Order hay Hủy bỏ - Cancel? Em đã thấy điều đó trên một
số trang web."
"Đúng. Khi họ kích Order, chúng ta lưu đơn đặt hàng và
in đơn cho nhân viên pha chế. Nếu họ hủy bỏ, chúng ta
sẽ quên nó đi. Trong cả hai trường hợp, chúng ta đều
quay lại phần đầu của menu chính và hỏi tên khách hàng
tiếp theo. "
Simon lấy một tờ giấy và hí hoáy vẽ. "Đầu tiên chúng ta
nên trực quan kế hoạch bằng thuật toán. Khi cả hai
chúng ta đều đồng ý về cách hoạt động, em có thể bắt
đầu viết code. Thảo luận về chương trình tương lai của
em bằng những từ ngữ và sơ đồ đơn giản trước khi em
bắt đầu code luôn là một cách thực hành tốt.”

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Việc đầu tiên chúng ta cần làm ở đây là nhận đơn đặt
hàng,” Simon bắt đầu giải thích. "Em thấy đấy, anh đặt
nó ở đây là 'Nhận đặt hàng' – Get order."

"Thế tất cả các thực đơn với flavor and toppings của
chúng ta ở đâu? Tại sao anh không đặt chúng ở đây?"
Erik hỏi.
“Anh quyết định sử dụng một khối có tên 'Nhận đơn đặt
hàng' chứa tất cả các menu. Cách suy nghĩ phổ biến là
cho các khối lớn trước rồi sau đó làm việc chi tiết riêng

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

biệt cho từng khối một. Tiện thể nói tới thì đây là một lý
do nữa khiến các lập trình viên sử dụng các hàm. Đầu
tiên họ nghĩ về chương trình theo các khối lớn và sau đó
mô tả từng khối trong một sơ đồ riêng. Hãy tưởng
tượng giả sử chúng ta gộp các chi tiết nhỏ vào một sơ
đồ duy nhất thì sao. Nếu thế thì thật không thể hiểu nổi
thuật toán chính!"
"Chúng ta tiếp tục nào” Simon cổ vũ. "Thế là chúng ta
nhận đơn đặt hàng và yêu cầu khách hàng xác nhận. Họ
có thể hủy rồi chúng ta quay lại menu đầu tiên: 'Chào
mừng đến với Tiệm cà phê của Erik', đại loại như thế."
"Trường hợp khách hàng xác nhận đơn đặt hàng,"
Simon nói, "thì chúng ta lưu lại và in đơn."
“Được rồi, em hiểu rằng chúng ta nên in đơn để pha chế
đồ uống,” Erik lên tiếng. "Thế tại sao chúng ta phải lưu
nhỉ? Lưu đơn đặt hàng có ý nghĩa gì?"
"Đầu tiên, em không thấy thật là tốt nếu biết được cả
ngày quán cà phê em đã phục vụ bao nhiêu người à?"
“Em biết trước rồi mà,” Erik đáp. "Hôm đó em chuẩn bị
năm ly."
" Đừng quên rằng chúng ta đang nói về một quán cà phê
thực sự. Mọi người làm việc cả ngày và phục vụ hàng
chục đến hàng trăm khách hàng. Một vài người bạn của
anh từng làm việc ở mấy quán cà phê và anh có thể đảm
bảo với em rằng họ biết rất rõ họ phục vụ bao nhiêu
khách hàng mỗi ngày."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Còn có lý do nữa" Simon tiếp tục nói "Liệu rằng người


quản lý cửa hàng cà phê có nên biết họ đang có gì trong
cửa hàng và họ nên nhập kho cái gì không? Em còn nhớ
chúng ta đã nói về việc thay đổi thực đơn không? Ví dụ,
họ không gọi hương vị caramel kịp thời và họ phải loại
bỏ món đấy khỏi menu. Tại sao họ không nhập vào món
đó? Là vì họ không đếm xem khách hàng của họ đã đặt
bao nhiêu phần hương vị caramel. Vì vậy, chúng ta phải
lưu tất cả các đơn hàng, phân tích lẫn đặt hàng flavor và
toppings nếu lượng tồn kho không đủ."
“Em chưa nghĩ về việc ấy” Erik nói. "Đúng, lưu các đơn
đặt hàng là một ý tưởng hay; anh nói đúng. Thế chúng
ta làm điều đó như thế nào?"
“Có vài cách,” Simon trả lời. "Chúng ta có thể sử dụng
file hoặc có thể sử dụng cơ sở dữ liệu. Tất nhiên, tất cả
các ứng dụng nghiêm túc đều sử dụng cơ sở dữ liệu. Anh
nghĩ chúng ta nên bắt đầu với tệp và sau đó, nếu em đủ
can đảm, chúng ta cũng có thể sử dụng cơ sở dữ liệu."
"Vâng, em muốn chương trình của mình giống như
những ứng dụng thực thụ!" Erik nói. "Em cũng muốn
làm thử cơ sở dữ liệu!"
"Được," Simon nói, "nhưng hiện tại chúng ta hãy kết
thúc menu chính đã. Chúng ta sẽ lưu các đơn hàng ngay.
Nói tới đơn hàng," Simon lấy ra một tờ giấy khác, "đây
là nội dung bên trong khối 'Nhận đơn hàng'."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Hãy tạo sơ đồ riêng mình


Nếu bạn quyết định làm việc trong loại cửa hàng
khác, hãy tạo sơ đồ cho hàm get_order() riêng mình.
"Chúng ta đã viết hàm này rồi. Chúng ta chỉ không gọi
nó là hàm. Em thấy đấy: chúng ta đã tạo sẵn những hộp
thoại này để hỏi tên khách hàng, the drink, flavor và
topping. Chỉ có một điều mà chúng ta chưa làm, em thử
đoán xem?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Trả về đơn đặt hàng phải không ạ?" Erik hỏi. "Em thấy
rằng chúng ta chưa làm điều đó, nhưng em không biết
nó có nghĩa là gì ở đây."
"Hãy nhìn vào phía bên phải của sơ đồ. Đơn đặt hàng
của em giống như này, đồng ý chứ?"

"Chúng ta dùng hàm get_order() để thu thập tất cả thông


tin này, nhưng thay vì trả về bốn giá trị riêng biệt cho
name, drink, flavor và topping, anh muốn trả về một thứ
duy nhất mà anh sẽ gọi là đơn đặt hàng. Cái thứ duy nhất
đó chứa đựng một số giá trị đi cùng nhau như một tổng
thể."
"Em hiểu rồi, anh muốn sử dụng một list ở đây!" Erik đã
chia sẻ cái nhìn sâu sắc của bản thân.
"Đó là một lựa chọn đấy, mà anh nghĩ đến một thứ tốt
hơn. Trong Python, chúng ta có từ điển. Từ điển bình
thường là gì?"
“Ồ, đó là một cuốn sách có từ ngữ và ý nghĩa từ” Erik trả
lời. "Thêm phần dịch, nếu đó là từ điển Anh-Đức."
"Đúng rồi!" Simon nói. "Em có một từ và một giá trị liên
quan đến từ này. Giống thế này nhé" Thế rồi anh vẽ ra
một sơ đồ.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đó có thể là ý nghĩa hoặc bản dịch của từ. Trong


Python, chúng ta có một thứ tương tự như thế. Từ điển
Python sử dụng các từ mà chúng ta gọi là khóa để lấy
các giá trị liên quan đến chúng. Hãy nhìn đơn đặt hàng
của em. Em có một khóa được gọi là 'name' và giá trị của
nó là 'Erik'. Em có một khóa khác gọi là 'drink' và giá trị
của nó là 'decaf'. Tất cả đều giống như thế. Toàn bộ từ
điển được gọi là order và đây là kết quả mà chúng ta sẽ
trả về từ hàm này ."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Hãy thử với REPL đi" Simon gợi ý. "Kích REPL để đến
phiên tương tác."
Erik kích vào biểu tượng REPL và chuyển sang cửa sổ
tương tác. Cửa sổ hiện ra như thế này (phiên bản của
bạn có thể khác với ví dụ bên dưới—không sao cả đâu):

"Chúng ta bắt đầu với việc tạo một từ điển trống có tên
là order. Để tạo một từ điển trong Python, chúng ta sử
dụng dấu ngoặc nhọn {} để làm cho chúng trông khác

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

với danh sách - sử dụng dấu ngoặc vuông []. Nhập order
= {} rồi ENTER. Đơn đặt hàng của em kiểu này."
Erik gõ:
In[1]: order = {}
In[2]:
"Bây giờ chúng ta có thể thêm các item vào order. Chúng
ta hãy bắt đầu với name. Nhập order['name'] ='Erik'. Sau
đó thử in đơn hàng bằng một hàm print() đơn giản."
Erik gõ:
In[2]: order[‘name’] = ‘Erik’
In[3]: print(order)
{‘name’: ‘Erik’}
In[4]:
"Ơ, anh nói từ điển sử dụng dấu ngoặc nhọn. Thế tại sao
chúng ta lại sử dụng dấu ngoặc vuông ở đây?" Erik hỏi.
"Câu hỏi hay" Simon đã quá quen thuộc với tính năng
này của Python nên anh không thể tìm ra cách đơn giản
để giải thích nó ngay lập tức. Anh bắt đầu câu trả lời thế
này "À, chúng ta sử dụng dấu ngoặc nhọn để tạo từ điển.
Nhưng chúng ta sử dụng dấu ngoặc vuông để truy cập
từ điển, tức là khi chúng ta muốn lấy một item từ đó.
Theo nghĩa này, nó tương tự như danh sách—khi em
muốn lấy một item trong list em sử dụng dấu ngoặc
vuông. Sự khác biệt là với danh sách em sử dụng các
index là số nguyên. Với từ điển, em sử dụng các key
thường là chuỗi. Nếu em có một từ điển thông thường
để nhận nghĩa hoặc dịch một từ và em sử dụng index

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của nó—chẳng hạn như 546—điều đó sẽ rất bất tiện,


em thấy đúng chưa? Thay vào đó, em sử dụng chính từ
đó, chẳng hạn như 'con chó' và tìm ra thật là nhanh."
“Phải, phải,” Erik trả lời. "Em có nên thêm drink, flavor
và topping bây giờ không?"
"Ý kiến hay, tiếp tục làm nào!" Simon nói.
Thế rồi Erik tiếp tục làm tương tác:
In[4]: order[‘drink’] = ‘decaf’
In[5]: order[‘flavor’] = ‘vanilla’
In[6]: order[‘topping’] = ‘chocolate’
In[7]: print(order)
{‘name’: ‘Erik’, ‘drink’: ‘decaf’, ‘flavor’: ‘vanilla’, ‘topping’: ‘chocolate’}
In[8]:
"Chú ý chỗ này" Simon nói, "Key và giá trị của em luôn
đi theo cặp với dấu hai chấm : đứng giữa."
LƯỢT CỦA BẠN: Học từ điển với REPL
Mở REPL và làm việc với từ điển. Bạn có thể lặp lại
các lệnh của Erik hoặc tạo từ điển của riêng mình.
Hãy thử sử dụng các phím khác nhau. Cố gắng lưu
trữ một con số thay vì một chuỗi. Liệu nó có hoạt
động không?
"Cái này hay đấy, em thích rồi!" Erik nói. "Thế em có thể
in nó theo cách tốt hơn không - giống như em đã in
trước đây vậy?"
“Tất nhiên,” Simon nói. "Anh nghĩ em nên viết một hàm
mới làm điều này. Tức là chúng ta cần quay lại trình
editor để làm."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Đó sẽ là hàm thứ ba của em” Erik nói.


"Em đang tập đếm hả?" Simon mỉm cười. "Anh chắc
rằng chẳng bao lâu nữa em sẽ không còn đếm nổi các
hàm mà em đã viết!"
"Bây giờ chúng ta hãy quay lại trình soạn thảo và bắt
đầu viết chương trình menu chính," Simon nói tiếp.
Chúng ta sẽ sử dụng phương pháp thiết kế từ trên
xuống top-down ở đây."
"Cái gì thế?" Erik hỏi.
"Giống như những gì anh vừa chỉ cho em: đầu tiên
chúng ta phát triển thuật toán cho toàn bộ chương
trình. Chúng ta quyết định khối lớn là gì và làm thế nào
chúng ta chuyển từ khối này sang khối khác. Điều đó
thường bao gồm các quyết định như xác nhận hoặc hủy
đơn đặt hàng. Chúng ta có thể phát triển chương trình
chính và sử dụng các hàm như get_order() hoặc
print_order(). Chẳng thành vấn đề nếu chúng ta chưa có
các hàm này. Trước khi viết các hàm thực, chúng ta có
thể viết các hàm rất đơn giản chỉ in ra thông báo 'Tôi là
một hàm print_order()' và chỉ thế thôi. Một số người gọi
chúng là 'xí chỗ trước'. Khi chúng ta thấy rằng menu
chính hoạt động tốt và gọi đúng hàm - khi đó chúng ta
sẽ viết vào các hàm thực."
"Để anh giúp em chỗ này" Rồi Simon cầm lấy bàn phím.
"Đầu tiên, anh tạo một tệp mới và lưu nó với tên

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

main_menu.py. Sau đó, anh tạo một hàm mới gọi là


main_menu() với từ khóa def và các dấu ngoặc đơn."
"Hàm khác ư?" Erik hỏi.
"Chính xác, ở trong lập trình, chúng ta thường tạo các
hàm cho mọi thứ. Chương trình chính thường rất ngắn
và nó gọi một trong các hàm. Sau đó, hàm này gọi các
hàm khác, v.v. Vì vậy, một cách thực hành tốt là viết
ngay cả menu chính dưới dạng một hàm."
Simon tiếp tục giảng giải "Bây giờ hãy nhìn vào sơ đồ.
Em có thấy những mũi tên này quay trở lại 'Bắt đầu -
Start' không? Chúng thường có nghĩa là trong thuật
toán, em sẽ lặp đi lặp lại. Ngay khi quay lại 'Start', chúng
ta tiếp tục lặp đi lặp lại cùng một thuật toán. Và để lặp
lại điều gì đó trong một chương trình, chúng ta sử
dụng… cái gì nhỉ?"
"Một vòng lặp!" Erik trả lời ngay.
"Chính xác!" Simon xác nhận. "Chúng ta đã sử dụng hai
loại vòng lặp: vòng lặp for và vòng lặp while. Em chọn
sử dụng loại nào ở đây?"
“Em nghĩ nó nên là một vòng lặp while,” Erik đáp. "Menu
chính này trông tương tự như những gì chúng ta đã làm
trong menu drink: lặp lại câu hỏi và kiểm tra câu trả lời
của người dùng."
“Anh đồng ý,” Simon nói. "Hãy xem code nào, chỗ em đã
viết menu dưới dạng một hàm ấy. Hãy nhớ rằng, chúng
ta đã sử dụng while True: cần kiểm tra dữ liệu người
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

dùng nhập vào. Em nghĩ xem chúng ta nên kiểm tra điều
gì ở đây? Gợi ý: những thời điểm phải đưa ra quyết định
sẽ thường được vẽ dưới dạng hình thoi trên sơ đồ."

"Em thấy nó rồi!" Erik thốt lên. "Đó là chỗ chúng ta hỏi
người dùng xem họ muốn xác nhận hay hủy đơn đặt
hàng."
"Được rồi, chúng ta hãy bắt đầu viết đi thôi" Simon nói.
Erik gõ một hồi:
def main_menu() :
while True :
"Tiếp theo là gì ạ?" Cậu hỏi.
“Hãy xem sơ đồ” Simon trả lời.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Get order đúng không ạ?" Erik hỏi.


"Phải! Và hãy nhớ rằng, hàm get_order() sẽ trả về một từ
điển với order. Từ điển sẽ chứa tên khách hàng, thức
uống, hương vị, và tất cả những thứ còn lại. Chúng ta sẽ
đặt từ điển đó vào một biến gọi là order trong menu
chính. Chúng ta hãy cùng nhau viết đoạn code ngắn này
nào" và Simon thêm một dòng vào code của Erik.
def main_menu() :
while True :
order = get_order()
"Tiếp theo làm gì?" Anh hỏi cậu em.
“Bây giờ chúng ta phải hỏi khách hàng để họ xác nhận
đơn đặt hàng” Erik nói.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Tốt. Anh nghĩ chúng ta phải cho họ xem đơn order


trước khi hỏi" Rồi Simon thêm vào mấy dòng lệnh.
def main_menu() :
while True :
order = get_order()
print(“Check your order:”)
print_order(order)
confirm = input(“Confirm? Press Y to confirm, N to cancel:”)
"Xem chỗ này" Simon nói với Erik, "Anh dùng biến
order mà anh nhận được từ get_order() làm đối số cho
hàm tiếp theo, print_order(). Điều này rất phổ biến
trong lập trình: chúng ta gọi một hàm để làm một việc
gì đó, nó trả về một kết quả và sau đó chúng ta sử dụng
kết quả đó làm đầu vào cho một hàm khác."

“Em hiểu rồi,” Erik nói. "Giống như trong rạp chiếu
phim: nhân viên thu ngân in vé và đưa cho anh. Anh cầm
vé, tới lối vào anh đưa vé cho người đứng lối vào để
kiểm tra."
"Chính xác, suy luận tốt đấy, Erik! Tiếp tục làm với nhau
nào: chúng ta vừa nhận được câu trả lời cho câu hỏi liệu
khách hàng có muốn xác nhận đơn đặt hàng hay không.
Bây giờ, như em vừa nói, chúng ta phải kiểm tra câu trả

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

lời và quyết định xem nên làm gì tiếp theo. Giống hệt
như ở rạp chiếu phim: họ kiểm tra vé nếu vé em đúng
thì mới quyết định cho phép vào hay không. Nào thêm
những dòng này đi. Nhìn sơ đồ xem nếu người dùng trả
lời 'Có', chúng ta sẽ làm gì?"

“Save order và print order,” Erik trả lời khi nhìn vào sơ
đồ của ông anh.
"Được rồi, thế lỡ người dùng muốn hủy và trả lời
'Không'?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chúng ta không làm gì cả, chỉ cần quay lại Start. Nhưng
em không biết làm thế nào cả. Em chỉ có một mũi tên ở
đây."
"Có một từ đơn giản cho mũi tên này trong Python và từ
này là continue. Nó có nghĩa là 'không thực hiện phần còn
lại của vòng lặp và tiếp tục vòng lặp từ đầu'. Dễ lắm phải
không?" Thế rồi Simon gõ thêm những dòng sau vào
hàm.
def main_menu() :
while True :
order = get_order()
print(“Check your order:”)
print_order(order)
confirm = input(“Confirm? Press Y to confirm, N to cancel:”)
if confirm == “Y” or confirm == “y”:
save_order(order)
print(“Thanks for your order:”)
print_order(order)
else:
continue
“Em thấy rằng anh đã thêm hai hàm nữa: save_order() và
print_order(),” Erik nói. “Thế nhưng chúng ta không có
chúng ở đây…”
"Nào viết chúng luôn thôi!" Simon hô lên. "Bây giờ
chúng ta sẽ viết các hàm rất đơn giản. Chúng sẽ không
làm gì cả, chúng sẽ chỉ in một cái gì đó như 'saving
order…' để chúng ta thấy rằng chúng đã được gọi. Sau
này, chúng ta sẽ cải thiện hàm để làm những việc hữu
ích hơn ."
Simon đã thêm các hàm bên dưới hàm main_menu():
def get_order() :
return{}

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

def print_order(order) :
print(order)
return

def save_order(order) :
print(“Saving order …”)
return
Anh giải thích cho Erik: "Hàm get_order() là cái em đã
viết rồi. Chúng ta sẽ chuyển code của em vào đây, nhưng
bây giờ nó không làm gì cả. Không có menu, không có
hội thoại, nhưng nó phải trả về order. Hãy nhớ rằng,
order là một từ điển có các khóa như 'name', 'drink' và
các từ khác. Trong trường hợp này, hàm chỉ trả về một
từ điển trống, chính là một cặp dấu ngoặc nhọn. Chỗ này
giờ vẫn ổn phải không?"
“Vâng,” Erik trả lời. "Vậy ý anh là chúng ta sẽ sao chép
các hàm trước đây của em từ tệp trước đó sang tệp này,
có phải không ạ?"
“Chính xác,” Simon đáp. "Có những lúc, khi một chương
trình trở nên lớn, ý tưởng hay là nhóm các hàm vào các
tệp riêng biệt. Nhưng trong trường hợp của chúng ta,
việc giữ mọi thứ trong một tệp sẽ dễ dàng hơn."
"Cái hàm print_order()," Simon tiếp tục nói, "chỉ in thứ
tự mà nó nhận được thông qua đối số. Trong trường
hợp này, ta sử dụng hàm print() tiêu chuẩn của Python,
nhưng chúng ta sẽ làm cho nó đẹp hơn sau này. Em đã
làm rồi đó, có nhớ không?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nhớ lắm anh!" Erik nói. "Em nghĩ chúng ta có thể làm
cho nó trông giống như một hóa đơn quán cà phê thực
thụ."
“Ý kiến hay đấy,” Simon nói. "Hàm save_order() không
làm gì khác ngoài việc in 'Đang lưu đơn hàng...' Giờ thì
ổn rồi, chúng ta sẽ viết nó sau. Lúc này, chúng ta đã sẵn
sàng gọi hàm main_menu() và kiểm tra thuật toán. Hãy
tiếp tục làm và thêm lệnh gọi cho main_menu() ở cuối
và chạy nó đi. Chương trình chính của em sẽ chỉ bao
gồm lệnh gọi hàm này thôi."
Erik gõ thêm lời gọi hàm để toàn bộ chương trình, hiện
giờ nó trông như sau:
Listing 6.1 main_menu.py
def main_menu() :
while True :
order = get_order()
print(“Check your order:”)
print_order(order)
confirm = input(“Confirm? Press Y to confirm, N to cancel:”)
if confirm == “Y” or confirm == “y”:
save_order(order)
print(“Thanks for your order:”)
print_order(order)
else:
continue

def get_order() :
return{}

def print_order(order) :
print(order)
return

def save_order(order) :
print(“Saving order …”)
return

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

main_menu()
LƯỢT CỦA BẠN: Tạo main menu
Viết hàm main menu tương tự như hàm mà Erik
vừa tạo. Vui lòng thay đổi các câu đối thoại.
Cậu bấm Run và chương trình ra kết quả:
Check your order:
{}
Confirm? Press Y to confirm, N to cancel:
Rồi cậu gõ "y" và nhận được dòng này:
Saving order …
Thanks for your order:
{}
Check your order:
{}
Confirm? Press Y to confirm, N to cancel:
"Tại sao nó bảo em 'Kiểm tra đơn đặt hàng'?" Erik hỏi.
"Bởi vì nó là một vòng lặp!" Simon nói. "Sau khi em trả
lời 'y' cho câu hỏi xác nhận, nó sẽ quay lại phần đầu của
vòng lặp. Và trong lúc chúng ta chưa thêm hộp thoại
menu, nó sẽ in đơn hàng trống. Mọi thứ hoạt động đúng
như mong đợi. Bây giờ hãy thử trả lời ' n' cho câu hỏi."
Erik gõ 'n' và nhận được kết quả.
Confirm? Press Y to confirm, N to cancel: n
Check your order:
{}
Confirm? Press Y to confirm, N to cancel:
"Em có thấy sự khác biệt không?" Simon hỏi.
"Em thấy rằng lần này nó không in 'Saving order … -
Đang lưu đơn hàng ...'. Điều đó có nghĩa là nó nằm trên
mũi tên ngắn ở bên phải sơ đồ của anh."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Xuất sắc!" Simon rất vui khi thấy Erik thực sự hiểu sơ
đồ thuật toán.
"Anh nghĩ hôm nay chúng ta đã tiến bộ tốt: main menu
của chúng ta hoạt động rồi. Ngày mai chúng ta sẽ viết
các hàm thực tế sẽ làm những gì chúng ta muốn. Giờ thì

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

hãy kết thúc và xem lại những gì chúng ta đã học được


trong ngày."
"Chúng ta lại sử dụng vòng lặp while!" Erik nói.
"Phải rồi! Và em đã dùng được kiến thức em học được
khi làm việc với thực đơn," Simon xác nhận.
"Chúng ta học cả về từ điển. Chúng giống như từ điển
bình thường, nhưng anh có thể lưu trữ mọi thứ ở đó,
không chỉ là phần giải nghĩa từ."
"Đúng, chính xác rồi! Trong từ điển order đơn giản của
chúng ta, ta giữ name, drink và flavor. Nhưng trong một
từ điển phức tạp hơn, em có thể giữ định dạng số — ví
dụ: giá cả — có khi còn cả danh sách và các từ điển khác.
Từ điển thực sự hữu ích trong Python và em sẽ sử dụng
chúng mọi lúc."
“Em cũng thích cách anh tạo ra các hàm đơn giản chỉ để
kiểm tra menu chính,” Erik nói. "Anh nói nó được gọi là
'top – down từ trên xuống', đúng không ạ?"
“Chuẩn rồi” Simon trả lời. "Như em có thể đoán ra: có
một cách tiếp cận 'từ dưới lên'. Trong trường hợp đó,
trước tiên mọi người tạo các hàm, kiểm tra chúng đúng
cách, sau đó kết hợp chúng thành một chương trình lớn.
Theo một nghĩa nào đó, chúng ta cũng đã sử dụng cách
tiếp cận này khi em tạo và đã thử nghiệm hàm menu()
đầu tiên đó. Bây giờ chúng ta sẽ sử dụng hàm của em
trong chương trình lớn hơn."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Đến lúc nghỉ ngơi rồi,” Simon nói tiếp. "Ngày mai chúng
ta sẽ làm việc với các hàm đã được sử dụng trong main
menu."

6.1 Những điều mới mà bạn đã học được


ngày hôm nay

● Cách tiếp cận từ trên xuống


Trước tiên, bạn phát triển "bức tranh toàn cảnh" về ứng
dụng của mình và sử dụng các hàm đơn giản chỉ in nội
dung nào đó thay vì thực hiện công việc thực tế. Khi
thuật toán chính hoạt động tốt, bạn phát triển các hàm
thực tế.
● Từ điển
Từ điển Python có thể lưu trữ các cặp key và value. Bạn
có thể gán giá trị cho các key và bạn có thể nhanh chóng
tìm thấy chúng theo key.
● Lưu đồ
Các lập trình viên thường sử dụng sơ đồ để thảo luận về
các thuật toán của họ trước khi bắt đầu viết code. Thông
thường, hình chữ nhật có nghĩa là một quy trình nào đó,
hình thoi có nghĩa là điểm quyết định với câu hỏi
Có/Không. Cũng có các biểu tượng cho đầu vào, sử dụng
tài liệu, sử dụng cơ sở dữ liệu và những thứ khác. Chúng
ta sẽ giới thiệu chúng sau.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

6.2 Code cho chương này

Bạn có thể tìm thấy code cho chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch06

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Tạo hàm: Nhận đơn hàng và in


Chương này bao gồm
 Erik tạo ra các hàm thực tế để nhận đơn đặt
hàng và in ra
 Erik sử dụng từ điển để lưu trữ và in đơn đặt
hàng của khách hàng
 Chương trình của Erik hiện đang hoạt động như
kế hoạch!
 Erik và Simon định viết hàm lưu đơn hàng

"Hôm qua chúng ta đã tạo menu chính phải không?"


Simon bắt đầu cuộc nói chuyện với Erik. "Thậm chí
chúng ta còn thử nghiệm cả hàm menu chính."
“Vâng, nhưng nó chẳng giúp ích được gì,” Erik nói.
"Đúng!" Simon nói. "Em có nhớ là chúng ta đã nói về
cách tiếp cận 'từ trên xuống' phải không? Chúng ta đã
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

tạo các hàm trống chỉ để kiểm tra menu chính. Bây giờ
là lúc để chúng làm điều gì đó thực tế. Hãy mở tệp
Python đã tạo các menu từ file ra đi. Nó tên là menu_files.
py."
Erik mở file ra và bây giờ cậu ấy có hai tab trong trình
chỉnh sửa: một tab là file main_menu.py và tab kia chứa
file menu_files.py.
“Chuyển sang file main_menu.py và xem chúng ta phải viết
hàm nào ở đây,” Simon nói. "Em nhìn này, ba hàm:
get_order(), print_order() và save_order(). Chúng ta hãy
bắt đầu với get_order(). Sơ đồ của chúng ta ở đâu rồi?"

"Hãy bắt đầu với get_name. Chúng ta phải làm gì ở đây?"


Simon hỏi.
"Chúng ta chỉ hỏi 'bạn tên gì?' phải không ?," Erik trả lời.
"Phải rồi, tiếp nữa thì sao?"
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Sau đó chúng ta lưu nó trong một biến, chẳng hạn như


name."
“Gần đúng,” Simon nói. "Em hãy nhớ, chúng ta đã quyết
định rằng đơn hàng sẽ là một từ điển. Rồi chúng ta sẽ
lưu mọi thứ liên quan đến order – đặt hàng trong từ
điển này. Chẳng hạn là để lưu tên khách hàng thay vì
name = 'Erik', chúng ta nên viết order['name'] = 'Erik'. Chỉ
thay vì 'Erik', chúng ta sẽ sử dụng hàm input() giống như
em đã làm trong chương trình đầu tiên ấy." "Để em làm"
Erik nói và viết hàm này luôn:
def get_order():
order[‘name’] = input(“What’s your name:”)
return{}
“Giờ thì chạy thử xem sao.” Simon nói.
Erik bấm Run, chương trình hỏi tên và cậu nhập 'Erik'.
Nhưng sau đó cậu ta nhận được một vài dòng thông báo
lỗi.

"Cái gì thế này???" Cậu hỏi Simon.


"Đọc đi em, Python cho biết vấn đề của em đang xảy ra
ở đâu. Hãy đọc dòng cuối cùng."
“Cái tên 'order' không được xác định," Erik đọc dòng
thông báo.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đơn giản lắm" Simon giải thích. "Em đã cố gắng đặt


thông tin vào từ điển mà em chưa tạo ra. Sửa cái này dễ
lắm. Ta hãy tạo một từ điển rỗng. Nhớ là, chúng ta sử
dụng dấu ngoặc nhọn cho từ điển đấy nhé? Chỉ cần viết
order = {} trước dòng có input()."
Erik sửa hàm thành như hình sau:
def get_order():
order = {}
order[‘name’] = input(“What’s your name:”)
return{}
Rồi cậu chạy lại hàm. Lần này nó không hiện bất kỳ lỗi
nào.
What’s your name: Erik
Check your order:
{}
Confirm? Press Y to confirm, N to cancel: y
Saving order …
Thanks for your order:
{}
What’s your name:
"Giờ thì tốt hơn rồi" Cậu thốt lên.
"Đúng, đã tốt hơn rồi, nhưng xem này: nó vẫn in ra một
đơn đặt hàng trống. Em đã tạo một đơn đặt hàng, thậm
chí đã nhập tên rồi, nhưng hàm của em lại trả về một từ
điển trống. Hãy nhìn dòng này: return {}?"
"Đó chính là anh đã viết mà!" Erik chắc chắn đó không
phải lỗi của mình.
"Đúng, anh viết nó như thế để kiểm tra hàm main menu.
Nhưng bây giờ chúng ta phải trả về từ điển order thực
tế. Hãy sửa nó thành return order và xem nó có in tên
của em không."
Erik sửa hàm luôn:
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

def get_order():
order = {}
order[‘name’] = input(“What’s your name:”)
return order
Lại Run lại một lần nữa. Lần này cậu ta có:
What’s your name: Erik
Check your order:
{‘name’: ‘Erik’}
Confirm? Press Y to confirm, N to cancel:
"Hay quá, nó in tên em luôn này!"
"Xin chúc mừng!" Simon nói. "Bây giờ em đã biết cách
làm việc với từ điển rồi đó!
LƯỢT CỦA BẠN: Tạo hàm get_order()
Bắt đầu viết hàm get_order() cá nhân trong tệp
main_menu.py. Thêm thông tin đầu vào đầu tiên để có
tên của khách hàng. Kiểm tra nó bằng cách chạy
chương trình menu chính.

7.1 Lựa chọn của bạn là gì?

"Nào tiếp tục nào" Simon cổ vũ. "Chúng ta phải thêm


hàm menu() ngay bây giờ để đưa drink và flavor vào.
Nhưng chúng ta cũng cần hàm read_menu() để đọc menu
từ file. Sao chép cả hai hàm (menu() và read_menu()) từ
menu_files.py rồi dán chúng vào đây trong main_menu.py.
Dán chúng ngay trước dòng def get_order(): này."
"Xảy ra điều gì nếu em dán hàm sau dòng đó?" Erik
muốn biết tại sao anh trai lại hướng dẫn kỹ lưỡng đoạn
này như thế.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Nó sẽ không hoạt động” Simon trả lời em mình một


cách đơn giản và mỉm cười. "Được rồi, nếu em thực sự
muốn biết: chúng ta sẽ sử dụng hai hàm này trong hàm
get_order(). Trước tiên, chúng ta cần đọc nội dung menu
từ các file: drink, flavor, topping. Sau đó, chúng ta gọi
hàm menu () ba lần để có được các lựa chọn của khách
hàng. Và trước khi chúng ta sử dụng các hàm này, chúng
ta nên định nghĩa chúng. Nói cách khác, chúng ta nên
nói với Python rằng các hàm như vậy đã tồn tại và chúng
để làm gì. Đó là lý do tại sao chúng cần được dán trước
dòng def get_order():. Tiện thể thì đây là lý do vì sao
chúng ta sử dụng từ def để bắt đầu một hàm - chúng ta
cần định nghĩa nó."
“Được rồi,” Erik nói và bắt đầu sao chép các hàm. Trong
giây lát, tệp main_menu.py của cậu ấy trông như thế này:
Listing 7.1 main_menu.py
def main_menu() :
while True :
order = get_order()
print(“Check your order:”)
print_order(order)
confirm = input(“Confirm? Press Y to confirm, N to cancel:”)
if confirm == “Y” or confirm == “y”:
save_order(order)
print(“Thanks for your order:”)
print_order(order)
else:
continue

def menu(choices, title=”Erik’s Menu”, prompt=”Choose your item: ”):


print(title)
print(len(title)*’-‘)
i=1
for c in choices:
print (i, c)

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

i = i+1
while True:
choice=input(prompt)
allowed_answers=[]
for a in range(1, len(choices)+1) :
allowed_answers.append(str(a))
allowed_answers.append(‘X’)
allowed_answers.append(‘x’)
if choice in allowed_answers :
if choice == ‘X’ or choice == ‘x’ :
answer= ’’
break
else
answer=choices[int(choice)-1]
break
else:
print(“Enter number from 1 to”, len(choices))
answer= ’’
return answer

def read_menu(filename):
f = open(“drinks.txt”)
temp = f.readlines()
result = []
for item in temp:
new_item = item.strip()
result.append(new_item)
return result

def get_order() :
order = {}
order[“name”] = input(“What’s your name: ”)
return order

def print_order(order) :
print(order)
return

def save_order(order) :
print(“Saving order …”)
return

main_menu()

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chính xác!" Simon nói. "Bây giờ em đã biết quy tắc:


phải định nghĩa xác định thứ gì đó trước khi sử dụng nó
nhé. Em vừa thấy vấn đề khi gặp lỗi với từ điển order,
và bây giờ em thấy vấn đề với các hàm menu() và
read_menu() ở đây."
"Hiện giờ chúng ta đã sẵn sàng để sử dụng các hàm này
trong get_order()," Anh tiếp tục giảng giải. "Hãy ngắm kỹ
chương trình menu_files.py đi. Chúng ta phải làm gì
trước tiên?"
“Chúng ta đọc menu từ file,” Erik trả lời.
"Tốt, chúng ta hãy làm điều đó ở đây, mà là ở bên trong
hàm."
Erik đã thêm ba dòng vào hàm get_order():
def get_order():
order = {}
order[‘name’] = input(“What’s your name: ”)
drinks = read_menu(“drinks.txt”)
flavors = read_menu(“flavors.txt”)
toppings = read_menu(“toppings.txt”)
return order
Cậu phải điều chỉnh các dòng bằng cách thêm bốn
khoảng trắng trước mỗi dòng để chúng được thụt vào
cùng một mức độ như nhau [thụt so với lề như nhau tức
là khối hàm đồng mức same level].
"Thế bây giờ làm y hệt với ba hàm menu() phải không ạ?"
Cậu hỏi Simon.
"Đúng rồi, tiến lên nào!"
Erik sửa hàm của mình thành thế này:
def get_order():
order = {}
order[‘name’] = input(“What’s your name: ”)
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

drinks = read_menu(“drinks.txt”)
flavors = read_menu(“flavors.txt”)
toppings = read_menu(“toppings.txt”)
drink = menu(drinks, “Erik’s drinks”, “Choose your drink: ”)
flavor = menu(flavors, “Erik’s flavors”, “Choose your flavor: ”)
topping = menu(toppings, “Erik’s toppings”, “Choose your topping: ”)
return order
Cậu ấy tự hào với chương trình và nhìn Simon.
“Gần đúng rồi” Simon nói. "Em đã sao chép đúng, nhưng
em phải thay đổi code một chút để lưu các câu trả lời
vào trong từ điển order. Nó là một sửa nhỏ, em biết cách
thực hiện rồi đấy."
“À, em hiểu rồi,” Erik nói và sửa lại hàm. Bây giờ hàm
trông như hình sau:
Listing 7.2 main_menu.py
def get_order():
order = {}
order[‘name’] = input(“What’s your name: ”)
drinks = read_menu(“drinks.txt”)
flavors = read_menu(“flavors.txt”)
toppings = read_menu(“toppings.txt”)
order[“drink”] = menu(drinks, “Erik’s drinks”, “Choose your drink: ”)
order[“flavor”] = menu(flavors, “Erik’s flavors”, “Choose your
flavor: ”)
order[“topping”] = menu(toppings, “Erik’s toppings”, “Choose your
topping: ”)
return order
Simon khuyến khích em mình: "Xong rùi, chạy chương
trình đê!"
Erik bấm nút Run chương trình.
What’s your name: Erik
Erik’s drinks
-----------
1 chocolate
2 coffee
3 decaf
Choose your item: 1
Erik’s flavors
------------
1 caramel
2 vanilla

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

3 pepermint
4 raspberry
5 plain
Choose your flavor: 2
Erik’s toppings
-------------
1 chocolate
2 cinnamon
3 caramel
Choose your topping: 3
Check your order:
{‘name’: ‘Erik’, ‘drink’: ‘coffee’, ‘flavor’: ‘vanilla’, ‘topping’: ‘caramel’}
Confirm? Press Y to confirm, N to cancel: y
Saving order …
Thanks for your order:
{‘name’: ‘Erik’, ‘drink’: ‘coffee’, ‘flavor’: ‘vanilla’, ‘topping’: ‘caramel’}
What’s your name:
"Ồ!" Cậu ấy thực sự hạnh phúc. "Em đã viết một chương
trình hơn 70 dòng và nó hoạt động rồi!"
"Đúng, em đã làm được! Và nó thực sự hoạt động!"
Simon xác nhận và mỉm cười.
LƯỢT CỦA BẠN: Thêm các lựa chọn menu vào
chương trình của bạn
Thêm hai hàm menu() và read_menu() như bạn thấy
trong chương trình trước vào tệp main_menu.py. Kiểm
tra chương trình bằng cách chạy nó và nhập các lựa
chọn vào. Hãy thử nhập sai các lựa chọn và chắc
chắn rằng hàm menu() không cho phép bạn làm
chuyện đó.

7.2 In ra!

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nhưng vẫn còn thiếu một cái gì đó... Phần Order trông
không chuyên nghiệp lắm. Nó chưa được giống một
quán cà phê thực thụ..." Simon tiếp tục.
"Em hiểu rồi, nó phải nằm trong hàm print_order(),
đúng không ạ?" Erik gợi ý.
"Đúng, đúng rồi. Chuyển đến hàm print_order() trong tệp
main_menu.py của em. Hãy bắt đầu in đơn đặt hàng."
Hàm print_order() của Erik trông như thế này:
def print_order(order):
print(order)
return
“Ở đây chúng ta sử dụng hàm in mặc định do Python
cung cấp” Simon tiếp tục nói. "Python có thể in từ điển,
nhưng không đẹp lắm. Để gỡ lỗi thì không khó, nhưng
đối với các đơn đặt hàng và biên lai thực, chúng ta phải
làm cho nó đẹp hơn. Chắc em đã biết làm rồi, phải
không?"
"Ý anh là - em in những đường gạch ngang phải không
ạ? Đúng rồi, nó đẹp hơn."
"Được rồi, hãy làm điều gì đó tương tự như những gì em
đã làm ở cuối tệp menu_files.py. Em có thể sao chép
những dòng đó bắt đầu bằng chữ print ấy. Chỉ cần đừng
quên giữ đúng dấu đầu dòng và đảm bảo rằng em sử
dụng từ điển và không phải biến đơn giản. À, với lại
đừng quên rằng hiện tại chúng ta có tên của khách hàng
rồi. Anh nghĩ em nên sử dụng nó trong hàm của mình.
Em đã sẵn sàng chưa?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Rồi ạ,” Erik trả lời và bắt đầu làm việc với hàm. Cậu ấy
đã kết thúc với điều này:
def print_order(order):
print(“Here is your order, ”, order[“name”])
print(“Main product: ”, order[“drink”])
print(“Flavor: ”, order[“flavor”])
print(“Topping: ”, order[“topping”])
print(“Thanks for your order!”)
return
LƯỢT CỦA BẠN: Thêm hàm print_order()
Thêm hàm print_order() vào tệp main_menu.py. Vui lòng
sử dụng các trang trí như dấu gạch ngang (-), dấu
gạch dưới (_) hoặc dấu bằng (=) để làm cho đơn
hàng của bạn trông giống như cái bạn từng thấy ở
đâu đó. Hãy lấy hóa đơn từ các nhà hàng, quán cà
phê, cửa hàng kem và xem liệu bạn có thể làm cho
biên lai của mình trông giống như vậy không.
Cậu chạy lại chương trình và thu được kết quả đẹp hơn
nhiều:
Here is your order, Erik
Main product: coffee
Flavor: vanilla
Topping: caramel
Thank for your order!
Confirm? Press Y to confirm, N to cancel:
"Ừ, Tốt hơn nhiều rồi em!" Simon nói. "Đúng rồi, em có
thể thêm các trang trí như dấu gạch ngang hay đường
vạch dọc, nó tùy thuộc cả vào em. Nhưng anh có thể nói
rằng em đã làm rất tốt với tư cách là một lập trình viên.
Em đã viết một số hàm rất hữu ích, em đã sắp xếp chúng
đúng cách và em đã test thử chúng. Làm tốt lắm, Erik,
anh thực sự tự hào về em!"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Ngoài ra, chúng ta đã học về từ điển và em đã sử dụng


được rồi" Erik cảm thấy rằng đây là "thời gian tổng kết"
và cậu ấy nên đề cập đến mọi thứ cậu đã học và sử dụng
ngày hôm nay.
“Phải, phải,” Simon xác nhận. "Từ điển rất quan trọng
trong Python. Chúng ta hay sử dụng chúng trong các
chương trình. Sau này chúng ta sẽ tìm hiểu thêm."
"Anh nói chúng ta cũng nên lưu lại order của mình bằng
cách nào đó. Chúng ta sẽ làm điều đó vào ngày mai chứ?"
Erik hỏi.
“Được, chắc chắn rồi” Simon nói. "Em có biết về JSON
không?" Anh hỏi.
"Jason à? Vâng, bọn em học cùng nhau lớp toán. Bạn ấy
thì sao ạ?"
"Không, không phải Jason đấy" Simon cười. "JSON là
một định dạng file mà chúng ta có thể sử dụng để lưu
các đơn đặt hàng quán cà phê. Chúng ta sẽ tìm hiểu về
nó vào ngày mai, được chứ?" “Được rồi,” Erik nói và
chạy đi chơi.

7.3 Những điều mới mà bạn đã học được


ngày hôm nay

● Định nghĩa biến và hàm


Trong Python, chúng ta phải định nghĩa các biến và hàm
trước khi sử dụng chúng. Đối với các biến, chỉ đơn giản
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

gán một giá trị trống. Đối với từ điển là: order = {}, đối
với chuỗi là: name = "". Các hàm nên được xác định bằng
cách sử dụng từ khóa def.

7.4 Code cho chương này

Bạn có thể tìm thấy code cho chương này ở đây:


https://github.com/pavelanni/lets-talk-python-book/tree/main/ch07

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Làm việc với JSON: Lưu đơn hàng

Chương này bao gồm


 Erik tìm hiểu về định dạng JSON và file
 Erik tìm hiểu về các modules Python
 Erik tạo danh sách của order
 Simon và Erik viết hàm lưu order vào file
JSON

“Hôm qua anh nói gì đó về Jason,” Erik hỏi Simon.


"Nhưng anh đã nói đó là một Jason khác, không phải là
bạn trong lớp toán của em."
"Phải, đó là một Jason khác," Simon mỉm cười. "Đó là
JSON, J-S-O-N, định dạng file mà chúng ta dùng để lưu
trữ dữ liệu."
"Giống như các file chúng ta dùng để lưu trữ các menu
phải không ạ?"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Ừ, cũng tương tự thế” Simon trả lời. "Định dạng này rất
tốt để lưu trữ dữ liệu có cấu trúc."
"Đó là gì ạ?" Erik hỏi.
"Có lúc em chỉ muốn lưu trữ một đoạn đoạn text hoặc
một hình ảnh. Thường thì, chúng không có cấu trúc cố
định. Đoạn text chỉ là đoạn text. Hình ảnh có thể lớn và
nhỏ, có thể đen trắng hoặc có màu. Nhưng nó không có
tý cấu trúc nào—nó chỉ là một loạt các pixel. Đây được
gọi là dữ liệu phi cấu trúc. Nhưng trong trường hợp của
em, mỗi đơn hàng đều có cấu trúc. Mỗi đơn hàng có tên
của khách hàng và tất cả các thành phần của đồ uống em
sẽ chuẩn bị. Tất cả đều như thế. Nó luôn có main drink,
flavor, topping. Bởi menu như thế, khách hàng cần trả
lời tất cả những câu hỏi này trước khi em in cái order
lưu trữ. Mặt khác, khách hàng không thể thêm bất cứ
thứ gì vào đơn đặt hàng."
"Chẳng hạn thêm một topping phải không ạ?" Erik hỏi.
“Phải,” Simon trả lời. "Đơn đặt hàng là một ví dụ về dữ
liệu có cấu trúc."
Erik không nghĩ rằng mình vừa tạo ra một thứ có cái tên
nghiêm túc như vậy.
“Đơn hàng của em được lưu trữ ở dạng từ điển,” Simon
tiếp tục nói “Mà em có biết chắc chắn rằng đối với mỗi
order, sẽ có các key từ điển (em có nhớ đó là gì không?)
được gọi là 'name', 'drink', ‘flavor', 'topping' ." Simon
kéo một sơ đồ vẽ hôm trước ra.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Định dạng JSON được tạo để lưu trữ loại dữ liệu có cấu
trúc này. Cùng nhau thực hành một tý nào. Y hệt như
chúng ta từng làm, trước tiên chúng ta sẽ tạo một
chương trình đơn giản rồi thử nghiệm một số thao tác
đơn giản. Sau đó, giống bài cũ, chúng ta sẽ dùng những
gì vừa làm với chương trình đơn giản này và áp dụng
vào chương trình chính để lưu các order vào một file.
Một ngày nhiều việc đây, vì thế mà có thể tiếp tục cả
trong ngày mai."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon tiếp tục nói: "Bây giờ hãy mở trình soạn thảo lên
và tạo một tệp mới. Lưu nó lại với tên dict_json.py chẳng
hạn."
Erik mở cửa sổ soạn thảo, kích Click New, rồi nhấn Save,
cậu nhập dict_json.py và click lại vào Save. Cậu ấy đã
quen thuộc với quy trình làm rồi.
"Bây giờ," Simon nói, "Hãy tạo một order mẫu."
"Order mẫu là gì ạ?"
"Đơn order của em là một từ điển, phải không?" Simon
bắt đầu giải thích. "Trong chương trình chính, em tạo
một từ điển trống rồi sau đó điền vào đó các giá trị em
nhận được từ khách hàng. Ở đây chúng ta phải bỏ qua
bước đó và hãy tưởng tượng rằng từ điển order của
chúng ta đã chứa đầy các lựa chọn của khách hàng. Để
anh bắt đầu nhé"
Simon nói và viết trong trình biên tập của Erik:

"Giờ em làm tiếp đi" Anh nói với cậu. "Đừng quên đóng
dấu ngoặc nhọn."
Erik làm xong từ điển order và đóng dấu ngoặc nhọn.
Bây giờ nó trông như thế này:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Em thấy anh đã thụt lề các dòng trong từ điển này" Cậu
hỏi anh trai. "Đó cũng là một quy tắc cho từ điển trong
Python sao?"
"Không phải" Simon đáp lại "Trong trường hợp này anh
làm vậy chỉ để nó trông đẹp đẹp tý thôi. Cũng dễ đọc
hơn chút. Anh có thể gộp tất cả các mục lại với nhau
trong một dòng hoặc bắt đầu từ đầu dòng, nhưng anh
nghĩ làm thế này trông đẹp hơn."
"Bây giờ" Anh tiếp tục nói "Chúng ta có một tập từ điển.
Và chúng ta muốn lưu nó vào một file. Anh đoán là anh
nên nhắc em về các hoạt động file từ điển."
“Phải rồi,” Erik nói, “Quá lâu rồi, em không nhớ nhiều
cho lắm.”
“Chắc chắn rồi” Simon nói. "Ngoài ra, em sẽ học được
một vài điều mới về file. Đầu tiên, chúng ta phải mở một
file. Để mở một tệp, chúng ta gọi một hàm có tên là
open()--tất nhiên rồi!--và chuyển tên file thành đối số.
Em đã biết mọi thứ về các hàm và đối số của chúng,
đúng chưa? Hàm đó trả về một file handle. Đó là một
object đặc biệt mà chương trình của chúng ta có thể
dùng ngay để làm việc với file này."
Simon viết thêm một dòng bên dưới từ điển mà Erik đã
tạo.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đây là cái mới đầu tiên. Nhìn thấy chữ 'w' này không?
Nó có nghĩa là chúng ta sẽ ghi vào file.

“Thế mà lúc chúng ta mở tệp menu, chúng ta không cần


dùng bất kỳ chữ cái nào” Erik nhớ lại.
"Em nói đúng rồi! Thật tốt là em nhớ nó," Simon nói.
"Đúng, chúng ta không dùng bất kỳ chữ cái nào trước
đây —nhân tiện cùng chủ đề, chúng được gọi là các chế
độ (mode)—bởi vì theo mặc định, khi anh không sử
dụng bất kỳ chữ cái nào, Python sẽ mở file ra đọc. Lần
này chúng ta muốn ghi vào tệp này nên chúng ta nói với
Python về điều đó."
"Em còn thấy rằng anh đặt tên file là 'orders.json'. Có
phải vì anh muốn sử dụng định dạng JSON mà anh đang
nhắc tới không?"
“Đúng, chính xác rồi” Simon trả lời. "Không bắt buộc,
nhưng đó là quy ước để thêm phần mở rộng '.json' vào
tệp JSON. Một điểm khác biệt nữa là khi chúng ta sử
dụng chế độ 'write', Python sẽ tạo ra file có tên này nếu
nó chưa có."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Vậy bây giờ thì sao ạ?" Erik hỏi. "Chúng ta ghi vào file
JSON này bằng cách nào? Lần trước chúng ta dùng
method'; đây có phải là tên gọi của chúng không?"
“Phải, em nhớ không nhầm đâu” Simon nói. "Nhưng lần
này chúng ta sẽ làm khác đi. Đó là do chúng ta viết dữ
liệu có cấu trúc, không phải chỉ là đoạn text thuần túy.
Chúng ta sẽ sử dụng một modules trong Python có tên
là json."
"Modules là gì ạ?" Erik hỏi ngay.
"Anh sẽ giải thích luôn đây" Simon mỉm cười. "Em có
nhớ, gần đây em đã viết một số hàm Python đúng
không? Ví dụ: để đọc các item menu từ một file và trả về
một list. Hãy tưởng tượng một trong những người bạn
của em muốn viết chương trình của riêng họ cho một
quán cà phê hoặc chương trình nào đó tương tự."
“Vâng” Erik nói “Gần đây, em có nói chuyện với Emily
và cô ấy nói rằng cô ấy muốn tạo một chương trình cho
một cửa hàng kem.”
"Tuyệt quá!" Simon nói. "Bây giờ em có thể giúp cô ấy
và chia sẻ các hàm mà em đã viết. Nó sẽ giúp cô ấy tiết
kiệm thời gian để chương trình của cô ấy sẵn sàng sớm
hơn. Các lập trình viên thường chia sẻ công việc của họ
để giúp đỡ lẫn nhau. Trong Python, em có thể nhóm các
hàm của mình với các hàm mà em muốn chia sẻ trong
một tệp và đưa nó cho Emily. Cô ấy có thể sao chép tệp

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đó vào máy tính của mình rồi kéo tệp đó vào chương
trình. Vì cô ấy đã import nhập file
vào nên cô ấy có thể sử dụng các hàm của em trong ứng
dụng của mình. Bây giờ cái file import đó có các hàm của
em là được gọi là một modules."
"Em mà không muốn chia sẻ các hàm thì sao ạ?" Erik
nói. "Em mất mấy ngày mới viết ra được!"
“Đúng là em đã viết nó," Simon nói. "Và em đã làm rất
tốt. Nhưng hãy nhớ rằng, rất nhiều người đã dành nhiều
ngày để viết các hàm khác trong Python và thậm chí là
chính cả Python nữa. Và họ đã chia sẻ công việc của
mình với các lập trình viên khác để em có thể sử dụng
Python và các hàm khác hoàn toàn miễn phí. Bằng cách
đó chúng ta giúp nhau làm việc trong các dự án của
mình. Sẽ chậm hơn nhiều nếu em và anh phải tự viết
mọi thứ từ đầu. Đó là lý do tại sao người ta sử dụng code
của người khác và cũng chia sẻ code của họ cho mọi
người. Nó thường được gọi là cộng đồng mã nguồn mở.
"
"Quay lại với JSON," Simon tiếp tục giảng giải. "Chúng ta
sẽ sử dụng modules có tên là json, do người khác viết.
Modules đó có thể đọc từ điển Python và chuyển đổi
chúng thành tệp JSON. Đi lên đầu tệp và thêm một dòng:
import json. Đây mới là dòng đầu tiên của file."
Erik đã làm thế. Đây là file đã cập nhật của cậu ấy.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Bây giờ chúng ta phải chuyển đổi từ điển ví dụ của em


thành JSON và ghi nó vào tệp mà chúng ta vừa mở,”
Simon nói. "Trong modules json, hàm này được gọi là
dump. Chúng ta gọi nó trong chương trình của em,
nhưng chúng ta phải nói với Python rằng nó nên tìm
hàm này trong modules json. Vì vậy, chúng ta gọi nó như
sau: json.dump(). Em chỉ cần truyền hai đối số: từ điển
và đối tượng file. Thêm hàm này vào cuối file. Từ điển
của em là order, đối tượng file là f ."
Erik thêm dòng này vào cuối chương trình:

Simon nói tiếp: "Bây giờ, đây là một việc nữa mà trước
đây chúng ta chưa làm với file. Chúng ta nên close tệp.
Điều này rất quan trọng, chúng ta hãy vẽ một sơ đồ khác
nào."
"Nhìn nè, đây là ba thành phần chính của máy tính: bộ
xử lý, bộ nhớ và ổ đĩa. Chương trình Python của em đang
chạy trên bộ xử lý. Tệp của em được lưu trữ trên ổ đĩa
trong một hệ thống tệp. Hệ thống tệp là những gì em
thấy trong Finder trên máy Mac và trong Explorer trên
Windows: thư mục (folder) và tệp (file). Khi em muốn

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

làm việc với một tệp trong Python, em mở tệp đó, làm
như xong ấy. Điều đó tạo ra một đối tượng tệp trong
chương trình của em. Khi em ghi vào tệp, em ghi vào bộ
nhớ máy tính. Sau đó, khi em muốn tệp của mình thực
sự được ghi vào hệ thống tệp trên ổ đĩa thì em đóng nó
lại."

"Chuyện này phức tạp quá!" Erik thấy bối rối. "Tại sao
chúng ta không ghi thẳng vào ổ đĩa?"
"Máy tính thật phức tạp, em nói đúng rồi!" Simon đồng
ý. "Lý do là bởi vì các kỹ sư máy tính cố gắng làm cho
máy tính hoạt động nhanh hơn. Động tác ghi vào ổ đĩa
sẽ khá chậm—chậm hơn nhiều so với ghi vào bộ nhớ.
Hãy tưởng tượng em đang viết chương trình của mình
trong một trình soạn thảo đoạn text. Nếu nó lưu mọi ký

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

tự em nhập ngay lập tức vào ổ đĩa thì nó sẽ rất chậm.


Em không thích làm việc với những chiếc máy tính
chậm chạp phải không?"
"Em ghét máy tính nào chạy chậm!" Erik trả lời đầy cảm
xúc.
"Để làm cho máy tính hoạt động nhanh hơn," Simon nói
tiếp, "Các kỹ sư quyết định lưu trữ dữ liệu trong bộ nhớ
và chỉ lưu vào ổ đĩa khi cần thiết. Họ sử dụng rất nhiều
thủ thuật để làm cho máy tính chạy nhanh hơn, đương
nhiên là, anh không biết tất cả. Có lẽ anh cần tìm hiểu
thêm ở trường đại học."
"Nào hãy quay lại chương trình của chúng ta. Hãy nhớ
rằng: các đối tượng tệp (file object) sử dụng các phương
thức (method). Trong trường hợp này, chúng ta gọi
f.close(). Điều đó sẽ đảm bảo order của chúng ta được
ghi vào tệp. Bây giờ hãy thêm nó sau dòng cuối cùng
trong chương trình đi."
Điều đó thật thoải mái— nhất là sau một lời giải thích
dài loằng ngoằng! Erik nhanh chóng gõ thêm và cậu có
được như hình dưới:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Run nó bây giờ thôi” Simon nói.


Erik kích Run và nhìn thấy dấu >>> quen thuộc ở cuối
cửa sổ. "Giờ thì sao ạ?" Cậu hỏi Simon.
"Không có chuyện gì xảy ra phải không?" Simon mỉm
cười, cảm nhận được sự bối rối của Erik. "Tất nhiên là
như thế, bởi vì em không yêu cầu Python in bất cứ thứ
gì ra. Tuy nhiên, có điều gì đó đã xảy ra đằng sau hậu
trường. Python đã mở một tệp có tên order.json, viết từ
điển của em vào đó và đóng nó lại. Bây giờ chúng ta phải
mở ra để kiểm tra xem nó đã làm đúng chưa. Sử dụng
trình soạn thảo đoạn text thuần túy để mở tệp. Em đang
sử dụng máy Mac nên nó sẽ là TextEdit từ thư mục Ứng
dụng. Trên Windows, đó là Notepad, trên Linux là gedit
hoặc Kate. Khởi động trình chỉnh sửa Editor và mở file.
Nó nằm trong thư mục chính của em, bên dưới mu_code
và được gọi là order.json."
Erik bật TextEdit, tìm file rồi mở ra. Đúng là, cậu ta đã
thấy order của mình:

LƯỢT CỦA BẠN: Lưu ví dụ order của bạn trong một


tệp JSON
Viết lại chương trình mà Erik vừa viết. Cố gắng sử
dụng một thứ tự hơi khác đi một chút. Chạy chương

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

trình và kiểm tra kết quả tệp JSON bằng trình soạn
thảo đoạn text. Hãy thử thay đổi order và chạy lại
chương trình. Tệp JSON của bạn có thay đổi không?
(Bạn có thể phải tải lại (reload) tệp trong trình soạn
thảo đoạn text.)

"Em thấy rồi chứ" Simon nói, "Đó là mẫu order của em,
được lưu trữ trong file. Hãy để anh bổ sung một số thứ
và em sẽ thấy tại sao các tệp JSON lại là chỗ lý tưởng để
lưu trữ các từ điển Python."
Simon lấy bàn phím và thay đổi lệnh gọi json.dump()
thành:

Anh ấy chạy lại khối mã và mở lại tệp order.json. Giờ


đây nó trông như thế này:

LƯỢT CỦA BẠN: Làm cho nó đẹp hơn


Thêm đối số indent=4 vào chương trình và kiểm tra
xem tệp JSON của bạn có thay đổi gì hay không.

"Nó trông giống hệt từ điển của em!" Erik nói.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Anh đã bảo rồi!" Simon thốt lên. "Chúng ta dùng JSON


để lưu trữ các đơn đặt hàng. Anh đã nói 'đơn đặt hàng',
nghĩa là bây giờ chúng ta phải học cách giữ một số đơn
đặt hàng và lưu trữ chúng trong một file. Chúng ta đã
biết cách Python lưu trữ một số item theo thứ tự— em
đã dùng nó cho các menu."
"Một danh sách list!" Erik nói.
"Đúng! Một danh sách trong Python có thể chứa nhiều
thứ khác nhau: định dạng chuỗi, số, thậm chí cả từ điển.
Trong trường hợp này, chúng ta sẽ có một list các từ
điển. Mỗi từ điển sẽ chứa một order, chúng ta sẽ thêm
từng cái một vào list. Một khách hàng mới, một đơn đặt
hàng mới, một từ điển mới trong danh sách. Để anh vẽ
sơ đồ."

"Hãy tạo một list các order" Simon tiếp tục. "Sao
chép order hiện có trong code và gọi nó là order1
chẳng hạn. Sau đó, thay đổi nội dung của order: tên,
đồ uống và những thứ khác."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik làm việc với code một lúc và cuối cùng cậu
nhận order bổ sung này, ngay dưới khối order đầu
tiên.

"Tốt rồi" Simon nói, "Bây giờ hãy tạo một list trống gọi
là orders. Lưu ý rằng nó ở dạng số nhiều—'orders'. Nó
rất giống với việc tạo một từ điển trống— cái này em đã
làm rồi. Chỉ thay dấu ngoặc nhọn bằng dấu ngoặc
vuông."
Erik gõ thêm dòng nữa vào bên dưới khối order thứ hai:

“Còn bây giờ chúng ta sẽ thêm cả hai đơn đặt hàng vào
danh sách,” Simon nói. "Tin hay không tùy em, nhưng
danh sách orders mà em vừa tạo cũng là một đối tượng.
Trong Python, thực tế thì mọi thứ đều là object cả. Và
mỗi object đều có các phương thức method mà em có
thể sử dụng. Em chỉ cần biết những phương thức nào
tồn tại cho đối tượng nào. Ví dụ như, phương thức gọi
là append() sẽ dùng cho tất cả các list. Nó thêm phần tử
mà em truyền làm đối số vào cuối danh sách. Hãy xem
đây, anh sẽ sử dụng nó để thêm order và order1 vào list
danh sách orders" Rồi Simon đã thêm hai dòng sau vào
bên dưới dòng tạo list danh sách orders.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nhưng làm thế nào để anh biết rằng anh nên sử dụng
append() ở đây?" Erik hỏi.
“Anh đã đọc nó trong tài liệu khi anh học Python,”
Simon vừa cười vừa trả lời. "Em dùng Google mà tìm
kiếm với cụm từ 'danh sách method của Python' và em
sẽ tìm thấy mọi thứ em cần biết."
"Bây giờ chúng ta thử lưu danh sách này dưới dạng
JSON," Simon tiếp tục giảng bài. "Điều duy nhất chúng
ta cần thay đổi là chúng ta muốn 'dump' cái gì vào tệp.
Chúng ta dùng order làm đối số cho hàm dump() để viết
ra một đơn đặt hàng. Bây giờ, hãy cùng nhau thay thế
nó bằng orders (số nhiều!) và xem cái gì sẽ thay đổi
nào."
Erik sửa dòng json.dump() thành:

Cậu chạy chương trình và mở lại tệp order.json.

LƯỢT CỦA BẠN: Lưu list lại

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Thêm một đơn hàng ví dụ khác, gọi nó là order2.


Tạo một danh sách orders. Lưu danh sách trong
cùng một tệp JSON. Kiểm tra kết quả bằng trình soạn
thảo đoạn text. Thêm hết các đơn đặt hàng mà bạn
có thể nghĩ ra và ghi chúng vào file. Liệu có giới hạn
bao nhiêu đơn đặt hàng được lưu lại không?

"Này, em muốn nói gì?" Simon hỏi. "Liệu đã giống những


đơn đặt hàng của em chưa?"
"Vâng, nó giống hệt Python rồi!" Erik nói. "Nhưng tại sao
chúng ta lại ghi các đơn đặt hàng của em vào file riêng
biệt? Nếu nó giống như Python, tại sao chúng ta không
viết các đơn đặt hàng của em vào chương trình Python
của chúng ta?"
"Câu hỏi hay!" Simon thực sự vui vì Erik muốn hiểu mọi
thứ. "Trước hết, chúng ta luôn muốn tách chương trình
ra khỏi dữ liệu. Hãy nhớ rằng, khi em chạy ứng dụng
Word, em không viết tài liệu của mình vào chương trình
Word. Em lưu chúng vào các tệp riêng biệt. Đó chính xác
là cái chúng ta làm ở đây. Chương trình của em có thể
lưu các đơn đặt hàng trong các tệp khác nhau, giả dụ:
cho từng ngày khác nhau. Tất cả những gì em phải làm
là thay đổi tên của tệp đầu ra, chẳng hạn như
orders.Monday.json, orders.Tuesday.json, v.v.
"Lý do thứ hai" Simon tiếp tục nói " Lý do định dạng này
được gọi là JSON vì nó là viết tắt của JavaScript Object
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Notation [Ký hiệu đối tượng JavaScript]. Nó được phát


minh lần đầu bởi những người sử dụng ngôn ngữ lập
trình JavaScript, sau đó các ngôn ngữ khác bắt đầu sử
dụng theo. Vì vậy, em có thể sử dụng Python để ghi đơn
đặt hàng của em vào tệp JSON, sau đó một số bạn bè của
em có thể muốn tạo một chương trình khác bằng
JavaScript, chương trình đó để đọc file json và in đơn
đặt hàng của em trên trang web chẳng hạn." "Vâng, em
có nghe nói một số bạn trong lớp biết làm JavaScript!"
Erik nói.
"Hay lắm! Em có thể thành lập một nhóm lập trình và
cùng nhau làm việc trên các ứng dụng," Simon nói.
"Nhưng hãy tiếp tục với chương trình mẫu của chúng ta.
Bây giờ chúng ta sẽ đọc các đơn đặt hàng từ tệp JSON và
lưu chúng vào một danh sách mới. Hãy gọi nó là
save_orders."
"Tại sao chúng ta đọc nó nếu chúng ta chỉ ghi nó vào
file?" Erik bối rối.
"Có lẽ anh đã không giải thích nó đúng cách" Simon trả
lời. "Trong chương trình mẫu này, chúng ta đang thực
hành một số thao tác với các tệp JSON, vì vậy chúng ta
biết rõ về chúng và có thể sử dụng trong chương trình
chính. Các lập trình viên thường làm điều này: họ tạo
các chương trình đơn giản để kiểm tra một số khái niệm
và ý tưởng. Để anh cho em xem kế hoạch cho chương
trình chính của chúng ta, em sẽ hiểu rõ hơn về đích đến
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của chúng ta." Simon lấy một tờ giấy khác rồi bắt đầu
vẽ.
"Đầu tiên, chúng ta kiểm tra xem file có tên 'orders.json'
có tồn tại hay không. Nếu tồn tại, chúng ta sẽ mở tệp đó
và đọc các đơn đặt hàng trước đó."

"Tại sao chúng ta cần đơn đặt hàng trước đó? Chúng ta
đã chuẩn bị chúng sẵn sàng rồi mà" Erik hỏi.
"Đúng, nhưng hãy nhớ rằng, có thể chúng ta muốn đếm
xem chúng ta đã phục vụ bao nhiêu khách hàng trong
hôm nay, hôm qua hoặc trong tháng trước. Hoặc đếm

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

xem chúng ta đã dùng bao nhiêu phần caramen và cần


biết đã đến lúc mua thêm chưa. Em cần có tất cả các đơn
đặt hàng nếu muốn quản lý việc kinh doanh quán cà phê
một cách nghiêm túc. Đó là lý do tại sao tất cả các doanh
nghiệp đều lưu giữ những hồ sơ này trong một thời gian
dài."
"Nếu chúng ta không có tập tin này thì sao ạ?" Erik hỏi.
“Điều đó có nghĩa là chúng ta vừa khai trương doanh
nghiệp và bắt đầu buôn bán” Simon cười. "Trong trường
hợp này, chúng ta tạo một danh sách trống và bắt đầu
nhận đơn đặt hàng. Tệp sẽ được tạo tự động khi chúng
ta mở tệp để ghi vào."

"Hãy nhìn vào sơ đồ này: ở đây chúng ta có danh sách


'orders' hoặc được lấp đầy bằng các đơn đặt hàng của
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

ngày trước hoặc trống. Và chúng ta bắt đầu nhận các


đơn đặt hàng và lưu chúng vào danh sách này. Sau khi
hoàn thành công việc trong ngày, chúng ta đóng tệp và
lưu tất cả các đơn đặt hàng vào ổ đĩa. Ngày hôm sau,
chúng ta mở lại tệp và tiếp tục nhận đơn đặt hàng. Tất
cả các đơn đặt hàng mới sẽ được nối thêm vào đơn đặt
hàng của ngày hôm trước."

LƯỢT CỦA BẠN: Hãy vẽ sơ đồ cá nhân bạn


Cố gắng vẽ sơ đồ cho chương trình của bạn mà
không cần nhìn sách.
Vẽ sơ đồ giúp bạn hiểu cách chương trình hoạt động
như thế nào.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đây có phải là cách các cửa hàng cà phê thực sự hoạt


động không ạ? Giống như Starbucks đúng không ạ?"
Erik hỏi.
"Đúng, khá giống" Simon mỉm cười. "Tất nhiên, họ sử
dụng cơ sở dữ liệu để đảm bảo độ tin cậy và bảo mật.
Form mẫu order của họ phức tạp hơn của chúng ta.
Nhưng toàn bộ quy trình giống nhau."
"Bây giờ khi em đã biết kế hoạch tổng thể, hãy tiếp tục
với chương trình đơn giản của chúng ta và đọc từ file đi.
Chúng ta sẽ ngẫm nghĩ đơn đặt hàng trước đó với một
danh sách mới có tên là 'saved_orders' và sau đó chúng
ta sẽ in nó ra để xem liệu chúng ta đã đọc đúng chưa. Để
làm điều đó, trong modules json có một hàm gọi là
load(). Nó hoạt động giống như hàm dump(): đầu tiên
chúng ta mở một tệp, nhưng lần này là để đọc chứ không
phải ghi. Sau đó, chúng ta gọi json.load( ) và truyền đối
tượng tệp làm đối số. Hàm trả về đối tượng mà nó đọc
từ tệp và chúng ta gán đối tượng đó cho một biến. Trong
trường hợp của chúng ta, nó sẽ là một danh sách các
đơn đặt hàng— định dạng từ điển, em nhớ nhé. Nghe có
vẻ phức tạp đúng không? Để anh giúp em một tay. Nó
ngắn hơn nhiều trong Python," Rồi Simon gõ thêm dòng
vào code của Erik. Đây là những gì anh ấy đã thêm vào
cuối chương trình:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Anh bấm Run và Erik nhìn thấy kết quả:

LƯỢT CỦA BẠN: Đọc từ tệp JSON


Thêm các dòng trước vào chương trình của bạn và
thử đọc từ tệp JSON mà bạn đã tạo ra. Bạn có nhận
được các đơn đặt hàng giống như trong ví dụ
không?

"Hôm nay, chúng ta đã học được rất nhiều kiến thức"


Simon nói. "Hãy nghỉ ngơi cho đến ngày mai. Ngày mai
chúng ta sẽ thêm các hàm này vào chương trình chính
và sau đó nó sẽ trở thành một ứng dụng quán cà phê
thực sự. Liệu em có thể tóm tắt gọn lại những gì chúng
ta đã làm hôm nay không?"
"Chúng ta đã tạo một tệp JSON từ từ điển Python của em
và nó trông rất giống Python. Sau đó, anh đã giải thích
cho em các thứ về file, bộ nhớ và ổ đĩa. Ngoài ra, chúng
ta cũng tạo một danh sách từ điển và lưu nó vào tệp."
"Và chúng ta cũng đã học về các modules Python và cách
nhập chúng," Simon thêm vào. "Đến giờ nà tình hình
đang tốt" anh nhận xét "Hãy tiếp tục vào ngày mai.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Chúng ta rất gần lúc hoàn thành phiên bản đầu tiên của
ứng dụng rồi."

8.1 Những điều mới mà bạn đã học được


ngày hôm nay

● JSON, ký hiệu đối tượng JavaScript


Là một định dạng được sử dụng để lưu trữ dữ liệu
có cấu trúc và có thể được sử dụng để trao đổi thông
tin giữa các chương trình.
● Modules Python
Là các nhóm hàm Python mà các lập trình viên khác
có thể sử dụng. Thông thường chúng được nhóm
vào file. Bạn phải nhập import các modules trước
khi sử dụng chúng.
● Danh sách từ điển
Danh sách có thể chứa các định dạng khác nhau:
chuỗi, số, từ điển, danh sách khác.
● Hoạt động tập tin
Bạn có thể mở các tập tin để đọc và viết. Bạn có thể
ghi dữ liệu vào tệp, nhưng nó được ghi trong bộ nhớ
của máy tính. Bạn nên đóng các tệp để lưu dữ liệu
vào ổ đĩa máy tính.
● Cộng đồng mã nguồn mở

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Là những người chia sẻ chương trình họ viết và giúp


nhau viết code tốt hơn.

8.2 Code cho chương này


Bạn có thể tìm thấy code cho chương này ở đây:
https://github.com/pavelanni/lets-talk-python-book/tree/main/ch08

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Hoàn thành menu: Một chương trình


thực tế

Chương này bao gồm


● Erik và Simon tạo hàm load và save trong chương
trình chính
● Simon thêm chức năng thoát tới menu chính và
hàm get_order()
● Simon giải thích lý do tại sao anh nghĩ Erik cần làm
chương trình thật
● Hai anh em bàn kế hoạch tương lai

"Bây giờ chúng ta hãy thực tế nào" Simon nói. "Hôm qua
chúng ta đã chơi với các order mẫu và các chương trình
đơn giản. Hôm nay đã đến lúc dùng những gì chúng ta
đã học được vào chương trình thực tế của mình."
"Vâng nào chúng ta hãy làm thôi!" Erik hào hứng nói.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Mở tệp main_menu.py lên, chúng ta đã viết menu chính


ở đây. Chúng ta nên thêm cặp hàm để làm việc với tệp
JSON. Nào hãy gọi lại những gì chúng ta phải làm trước
tiên đã" Rồi Simon lấy sơ đồ vẽ từ ngày hôm qua ra.

"Nào, chúng ta phải viết một hàm sẽ tải danh sách các
đơn đặt hàng từ tệp JSON. Nhưng ban đầu, nó phải kiểm
tra xem tệp có tồn tại hay không đã. Nếu chưa tồn tại,
chúng ta tạo một danh sách trống và trả về từ hàm này.
Nếu máy thấy tồn tại, chúng ta đọc nó, chuyển đổi JSON
thành danh sách Python và trả lại danh sách đó."
“Để anh giúp em” Simon cảm thấy Erik hơi bối rối.
"Thông thường, trong các hàm làm việc với tệp, chúng
ta truyền tên file làm đối số," rồi Simon bắt đầu hàm ở
cuối file, ngay trước dòng cuối cùng với main_menu():

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Bây giờ chúng ta phải kiểm tra xem tệp có tồn tại
không. Có một hàm đặc biệt cho việc đó và chúng ta có
thể tìm thấy nó trong modules os."
"'os' là gì ạ?" Erik hỏi.
"OS là viết tắt của 'hệ điều hành'. Hệ điều hành trong
máy tính quản lý tất cả các tệp và chương trình. Hệ điều
hành này làm việc với màn hình, bàn phím, loa và máy
quay video của em. Trên một máy tính thông thường,
HĐH có thể là Windows, macOS hoặc Linux. Trong
trường hợp của chúng ta, ta sẽ hỏi hệ điều hành xem
một tệp có tên như vậy có tồn tại trên máy tính này hay
không" Simon tiếp tục thêm một dòng:

"Xem nè, chúng ta dùng modules os ở đây. Điều đó có


nghĩa là chúng ta phải import nó giống như cách chúng
ta đã import modules json. Trong chương trình này,
chúng ta chưa import cái nào, vì vậy cần import cả hai."
Simon di chuyển con trỏ đến trên đầu tập tin và thêm
hai dòng:

Rồi anh đưa con trỏ trở lại hàm load_orders() và tiếp
tục giải thích. "Nếu file có rồi, chúng ta mở nó để đọc, sử
dụng hàm json.load() đọc từ tệp nhớ vào danh sách

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

orders và trả về danh sách." Anh ấy gõ thêm ba dòng


vào hàm.

"Liệu chuyện gì xảy ra nếu file không tồn tại? Chúng ta


chỉ cần tạo một danh sách trống và trả về nó."

"Bây giờ hàm tải thông tin load đã sẵn sàng!" Anh vừa
nói vừa nhìn Erik.
“Em không nghĩ mình có thể tự viết nó,” Erik nói.
"Tất nhiên, nó có vẻ phức tạp khi em làm điều đó lần
đầu tiên. Nhưng nhìn xem, em có thể đọc nó như thể nó
là tiếng Anh đơn giản, phải không?"
Erik nhìn lại hàm và cố gắng đọc nó. "Nếu tệp có tên
'filename' tồn tại, hãy mở tệp đó ra. Lưu tệp đó vào đối
tượng có tên 'f'. Sau đó tải từ tệp 'f' đó vào 'đơn hàng'.
Hmmm... rồi, em đọc được rồi ạ." Cậu cảm thấy ngạc
nhiên. Giờ đây cậu ấy có thể đọc Python và hiểu nó!
"Hàm tiếp theo khá dễ," Simon tiếp tục nói. "Anh nghĩ
em có thể tự viết nó nếu em xem tệp của mình nơi chúng
ta thực hành với các đơn đặt hàng mẫu. Hãy nhìn này,
ngay sau hai thao tác append(), có ba dòng mà chúng ta
cần ở đây. Chúng ta đã có một hàm gọi là save_order()
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

mà không làm gì khác ngoài việc in 'Saving order...'. Hãy


thay thế nó bằng một đơn hàng thực. Anh nghĩ nó nên
được gọi là save_orders() — số nhiều, bởi vì bây giờ
chúng ta đã biết cách lưu danh sách đơn hàng trong tệp
JSON, phải không?"
Simon viết phần đầu của hàm:

Anh giải thích: "Chúng ta chuyển danh sách các đơn đặt
hàng làm đối số đầu tiên. Sau đó, chúng ta truyền tên
của tệp mà chúng ta muốn lưu trữ. Bây giờ, em có thể
thêm ba dòng đó từ chương trình ngày hôm qua đã
làm."
Erik xem tệp 'dict_json.py' và sao chép ba dòng từ đó
sang. Bây giờ hàm trông như hình sau:

"Chúng ta kiểm tra nó ngay bây giờ được không?" Cậu


hỏi Simon.
“Chúng ta sắp xong tới nơi rồi” Simon trả lời. "Hãy nhìn
vào phần dưới cùng của tệp. Bây giờ chúng ta chỉ cần
gọi hàm main_menu(). Em có nhớ sơ đồ thứ hai của anh
hôm qua không?" Rồi anh lấy bản vẽ ra.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Chúng ta làm thế này trong hàm main_menu(). Chúng


ta chỉ cần chỉnh sửa một chút để phục vụ nhiều khách
hàng và lưu đơn hàng lại trong danh sách 'đơn hàng'. Để
làm điều đó, chúng ta phải chuyển danh sách đó vào
hàm main_menu()."
Anh ấy di chuyển con trỏ đến đầu tệp và thêm đối số
orders vào để xác định main_menu().

"Bây giờ," Anh ấy tiếp tục nói "Mỗi khi khách hàng nhập
một đơn đặt hàng mới, nó sẽ được thêm vào danh sách
'orders'. Trước khi chúng ta thêm danh sách làm đối số,
main_menu() không biết thêm đơn đặt hàng mới vào
đâu. Bây giờ chúng ta có thể sử dụng phương thức
append() và thêm nó vào 'orders.' Ngay sau khi khách
hàng xác nhận đơn hàng, chúng ta thêm nó vào danh
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

sách orders. Ở đây chúng ta sẽ không sử dụng hàm


save_order(). Chúng ta sẽ lưu tất cả các đơn hàng khi em
đóng chương trình." Và Simon sửa hàm main_menu()
thành ra:

"Và chúng ta cũng thay đổi chương trình chính thành ba


bước: tải đơn hàng, menu chính (nhận đơn hàng) và lưu
đơn hàng." Rồi anh ấy đã thêm ba dòng nữa vào cuối tập
tin. Bây giờ nó trông như thế này:

"Em có thể thử nó luôn bây giờ không?" Erik hỏi.


"Được thôi, cứ tự nhiên!" Simon trả lời.
Erik chạy chương trình, nhập tên của cậu ấy ở dòng
nhắc đầu tiên, sau đó chọn các thành phần đồ uống. Khi
chương trình yêu cầu xác nhận đơn hàng, cậu gõ "Y."
Chương trình quay lại lời nhắc "What’s your name: ".
"Ổn rồi," Erik nói, "Nó chạy rồi. Nhưng em kiểm các đơn
đặt hàng bằng cách nào? Chúng đã lưu trong tệp chưa?"
"Chúng ta cùng kiểm tra nào" Simon nói.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Hai anh em mở tệp 'orders.json' và ngạc nhiên khi thấy


nó vẫn chỉ chứa các đơn đặt hàng cũ từ các hoạt động
ngày hôm qua của họ. Ngay cả Simon cũng thấy bối rối.
"Để xem nào" anh nói. "Chúng ta mở tệp, chúng ta đọc
từ nó, chúng ta nhận đơn đặt hàng... Nhưng chúng ta
chưa từng ghi vào tệp vì chúng ta vẫn ở trong menu
chính! Và chúng ta chưa lúc nào chạm tới hàm
save_orders() đó! Hmmm... để anh nghĩ cách khắc phục
nó."
Erik mỉm cười. Người anh biết tuốt của cậu không biết
phải làm gì rồi.
Điều đó chỉ kéo dài một lúc.
Simon nói: "Anh hiểu rồi. Chúng ta chưa đưa cho người
dùng cách thoát khỏi menu chính. Chúng ta liên tục hỏi
tên người dùng, nhưng chúng ta muốn kết thúc chương
trình thì thế nào?"
“Em thấy rằng anh đã nhấn CONTROL + C khi anh muốn
dừng chương trình của em,” Erik nói.
"Đúng, anh đã làm điều đó, nhưng đó là cách không bình
thường để kết thúc chương trình. Khi anh làm vậy,
chương trình bị gián đoạn. Thông thường Python đưa
ra thông báo lỗi khi em làm điều đó. Khi một chương
trình bị gián đoạn, điều đó có nghĩa là nó không làm bất
cứ điều gì cả: nó không ghi lệnh của chúng ta vào tệp, nó
không đóng tệp. Nhấn CONTROL+C là một cách tồi để
kết thúc chương trình."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon dừng lại một chút và tiếp tục: "Chúng ta nên cung
cấp cho người dùng một cách bình thường để hoàn
thành chương trình."
"Giống như lệnh Thoát ở menu trong Word ạ?"
"Đúng, giống như vậy. Hãy nói với người dùng rằng nếu
họ muốn thoát, họ nên nhập 'X' và chỉ nhập 'X' khi được
hỏi về tên của họ. Xác suất để chúng ta có một khách
hàng có tên đầy đủ là 'X' là rất thấp. Thực tế gần như
bằng 0. Vì vậy, hãy làm như này: nếu trong hàm
get_order() khách hàng nhập tên 'X', thì chúng ta không
hỏi bất kỳ câu hỏi nào khác và trả về một đơn hàng
trống, như sau: order = { }. Sau đó danh sách này được
chuyển đến hàm main_menu() và nó quyết định: nếu nó
không trống, nó sẽ thêm thứ tự vào danh sách và tiếp
tục hoạt động. Chúng ta hãy vẽ một sơ đồ nào."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Đây sẽ là hàm get_order() được cập nhật của chúng ta.


Để anh giúp em viết nó," Thế là Simon cầm lấy bàn phím
của Erik và sửa hàm get_order().

"Tại sao anh kiểm tra cả 'X' và 'x'? Anh bảo người dùng
nhập 'X' thì họ nên nhập 'X' viết hoa, phải không ạ?" Erik
hỏi.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Người dùng thường không bận tâm đến việc nhấn


phím Shift. Họ có thể nhập 'X' hoặc 'x'. Vì vậy, chúng ta
nên kiểm tra cả hai. Phần còn lại của hàm chắc dễ hiểu
rồi — Anh chỉ làm theo sơ đồ mà chúng ta đã cùng nhau
tạo ra. "
"Bây giờ đến main menu" Simon tiếp tục nói. "Phải cần
một sơ đồ khác" Rồi anh ấy bắt đầu vẽ.

"Giống như thảo luận, nếu get_order() trả về một đơn


hàng trống, chúng ta sẽ thoát khỏi menu chính. Sau đó,
chương trình của chúng ta sẽ lưu các đơn hàng trong
tệp." Simon đã chỉnh sửa hàm main_menu() thành như
hình sau:
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Chỉnh sửa hàm menu chính


Chỉnh sửa hàm main menu tương tự như Simon đã
làm. Nếu bạn cần trợ giúp, cả chương trình cho
chương này có tại đây (here)

“Và nó thế này đây” Simon nói. "Chúng ta cùng test nó


đi. Lần này chỉ cần nhập một tên khác để em thấy rằng
nó đã được thêm vào tệp JSON."
Erik bắt đầu chương trình. Cậu lấy tên "Jason" khi
chương trình hỏi về tên. Cậu nhập phần còn lại của đơn
hàng và gõ "Y" để xác nhận đơn hàng. Chương trình lại
sang phần hỏi tên.
"Giờ thì hãy nhập 'x' và xem nó có thoát đúng lý không,"
Simon gợi ý.
Erik gõ 'x' và nhấn ENTER.
Bạn đã nhập 'X', đang thoát... chương trình thông báo và
quay lại dấu nhắc >>> Python quen thuộc.
“Bây giờ hãy kiểm tra tệp orders.json,” Simon nói.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik khởi động TextEdit và mở tệp JSON. Ở cuối cùng


của file, cậu tìm thấy đơn đặt hàng vừa xong tên là
'Jason'.
"Nó đã làm việc rồi!" Cậu hô to. "Nó đã lưu tất cả các đơn
đặt hàng trong tệp và bây giờ em có thể xem tất cả!"
"Đúng, em có thể làm thế," Simon nói và mỉm cười. Anh
ấy rất vui khi thấy một chương trình hoạt động hoàn
chỉnh, nhận lệnh, lưu trữ chúng trong tệp và được viết
bởi em trai!
"Chúc mừng em, Erik!" Simon nói. "Anh nghĩ bây giờ em
có thể nói rằng em đã tạo ra một ứng dụng thực sự. Hãy
nhìn nè, nó có đầu vào và đầu ra. Nó có cấu trúc dữ liệu
và thuật toán. Nó biết kiểm tra lỗi. Nó có bộ lưu trữ dữ
liệu. Và quan trọng nhất: nó đã hoạt động và rất hữu
ích— nó thu thập các đơn đặt hàng. Anh nó nghiêm túc
nhé: đó là một chương trình tốt và anh rất tự hào về em"
Như thường lệ, Simon vẽ một sơ đồ về cái mà anh ấy gọi
là chương trình thực.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Vâng, em cũng thích chương trình này,” Erik nói. "Nó


làm được những gì em muốn và có vẻ tốt. Nó in các đơn
đặt hàng gần giống như cái em đã thấy ở Starbucks.
Vâng, gần như vậy... Có lẽ em có thể thêm một vài dòng
hoặc dấu sao để làm cho nó đẹp hơn. Em có một số ý
tưởng nữa có thể thêm vào chương trình này."
"Em muốn thêm gì nữa?" Simon hỏi.
"Trước hết, em muốn biến nó thành một ứng dụng web.
Anh biết rồi đấy, có các menu và nút bấm. Nó phải trực
tuyến để em có thể mang theo iPad cá nhân và sử dụng."
"Ý tưởng tuyệt vời!" Simon nói. "Chúng ta hãy bắt đầu
làm vào tuần tới. Anh cũng có dăm ba ý tưởng," Và anh
ấy mỉm cười.
"Tại sao anh cười?" Erik hỏi.
"Anh nhớ là em cho là mình đã hoàn thành chương trình
sau ngày đầu tiên."
“Ha, vâng, em cũng nhớ ngày đấy” Erik nói. "Tất nhiên,
khi đó chương trình vẫn chưa sẵn sàng. Anh có ý kiến gì
khác không?"
Simon nói: "Anh sẽ thêm một số thứ vào cấu trúc dữ
liệu. Ví dụ: chúng ta có thể thêm ngày và giờ thực hiện
đơn đặt hàng. Thế là, chúng ta có thể biết số lượng
khách hàng đã phục vụ mỗi ngày hoặc mỗi tháng."
“Vâng, em nghĩ như vậy cũng hay” Erik đồng ý với ý
tưởng.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Sau đó, có lẽ chúng ta nên lưu các đơn đặt hàng vào kho
lưu trữ dữ liệu ngay sau khi chúng được nhập vào. Điều
đó sẽ đảm bảo rằng chúng ta giữ được tất cả các đơn đặt
hàng trước đó ngay cả khi chương trình bị lỗi và treo."
“Nhưng anh từng bảo là nó sẽ làm chương trình chậm
hơn mà,” Erik nhớ lại.
"Chỉ một chút thôi. Nhưng nó đáng giá—nếu không,
chúng ta có nguy cơ mất tất cả các đơn đặt hàng. Anh
đang nghĩ đến việc sử dụng cơ sở dữ liệu cho việc đó."
"Còn nữa," Simon tiếp tục nói "Chúng ta cần các hàm
như 'in tất cả các đơn đặt hàng' và 'đếm xem chúng ta
đã dùng bao nhiêu phần hương vani'. Phải thế nếu
chúng ta muốn biến chương trình của em thành một
ứng dụng kinh doanh thực sự."
“Tất nhiên, em muốn nó cần như thế” Erik nói. "Nhưng
trước tiên em muốn biến nó thành một ứng dụng web
và làm cho nó thật đẹp."
"Chắc chắn rồi, chúng ta có thể bắt tay vào làm trong
tuần tới."

LƯU Ý: Gửi bạn đọc


Trong các chương tiếp theo của cuốn sách này,
chúng ta sẽ tiếp tục cuộc hành trình của Erik và
Simon và cùng họ phát triển một ứng dụng web.
Nếu bạn muốn xem các cải tiến khác mà Simon đã
đề xuất, bạn sẽ tìm thấy chúng trên trang web đồng
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

hành với sách https://github.com/pavelanni/ lets-talk-


python-book.

9.1 Những điều mới mà bạn đã học được


ngày hôm nay

● Cách kiểm tra xem tệp có tồn tại không


Chúng tôi dùng modules os Python cho điều đó và
phương thức os.path.exists(). Bạn truyền tên file và nó
trả về Đúng hoặc Sai.

● Nhấn CONRTOL+C không phải là cách chuẩn chỉ để


kết thúc chương trình
Chúng tôi sử dụng nó khi chúng tôi muốn dừng hoạt
động một chương trình một cách bất thường. Các
chương trình tốt sẽ luôn cung cấp cho bạn một cách để
hoàn thành nó một cách bình thường.
● Một chương trình thực sự là gì
Chúng tôi đã học được rằng các chương trình thực tế có
đầu vào và đầu ra, cấu trúc dữ liệu và thuật toán, lưu trữ
dữ liệu và kiểm tra lỗi.

9.2 Code cho chương này


Bạn có thể tìm thấy code cho chương này ở đây:
https://github.com/pavelanni/lets-talk-python-book/tree/main/ch09

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Learning Flask: Ứng dụng web đầu


tiên của bạn

Chương này bao gồm


● Erik tạo ứng dụng web đơn giản đầu tiên của mình
● Simon giải thích cách Flask hoạt động (nó là gì)
● Emily và Erik làm việc trên một biểu mẫu web
● Menu nền tảng web của quán cà phê đầu tiên đã
sẵn sàng!

"Em nói rằng em muốn tạo một ứng dụng web hả?"
Simon hỏi Erik vào hôm sau.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Vâng, đúng rồi!" Erik nói. "Nếu không thì làm sao em
dùng được chương trình trên iPad?"
"Được rồi, chuẩn bị tinh thần sẵn sàng nhé: đó không
phải là một nhiệm vụ dễ dàng. Nó sẽ đòi hỏi sự chú tâm
ghê gớm của em đấy. Có thể em sẽ không hiểu hết mọi
thứ chúng ta làm ở đây. Nhưng đừng lo lắng, anh sẽ giúp
em một tay."
“Em biết, anh là một người anh tốt,” Erik nói và hầu như
không có chút mỉa mai nào trong câu nói.
"Chúng ta sẽ sử dụng Trình chỉnh sửa Mu người bạn tốt
cho ứng dụng web. Nó có một chế độ đặc biệt cho việc
đó. Khởi động trình chỉnh sửa và kích vào nút Mode ở
góc trên cùng bên trái."
Erik làm theo và nhìn thấy menu này:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Cuộn xuống dưới cùng,” Simon nói. "Tìm chế độ Web


và kích vào đó. Sau đó kích Ok."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Sau khi Erik làm xong, Simon chỉ vào góc dưới cùng bên
phải và nói: "Em có thấy từ 'Web' bên cạnh hình bánh
răng không? Chúng ta đã chuyển sang chế độ Web. Bây
giờ hãy xem chúng ta có thể làm gì với nó. Bấm vào
New."
Erik làm theo và ngay lập tức code Python xuất hiện
trong cửa sổ soạn thảo.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

“Thú vị đấy,” Cậu hô to. "Mu đã viết điều gì đó giúp em


nè, em chạy Run được không?"
"Được chứ, làm tiếp nào. Trước tiên, em phải lưu nó lại.
Gọi nó là 'first_app.py'."
Erik kích Run, nhập 'first_app.py' vào hộp thoại Lưu và
thấy kết quả như thế này ở cuối cửa sổ.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nó là gì ạ?" Cậu hỏi.


"Như này cho em biết rằng ứng dụng web đầu tiên của
em đang chạy. Xem thông báo này: 'Đang chạy trên
http://127.0.0.1:5000/'. Điều đó có nghĩa là em có thể truy
cập trình duyệt của mình và nhập địa chỉ này:
http://127.0.0.1:5000/.Đôi khi địa chỉ này còn được gọi là
URL hoặc Hệ thống định vị tài nguyên thống nhất —em
sẽ nghe thấy từ này mọi lúc khi làm việc với web. Hoặc

chỉ cần kích nút Run Trình duyệt Web trong trình
chỉnh sửa. Hãy thử và xem em có gì nào."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik mở một tab mới trong trình duyệt web và nhập địa
chỉ. Đây là những gì cậu ấy thấy:

"Từ từ đã, tất cả những thứ này đều do trình editor của
em viết sao?" Cậu hỏi Simon.
"Đúng, mà xem này, Mu gợi ý rằng phần còn lại em tự
viết," Simon nói và chỉ vào ví dụ code trên trang. "Mu
khuyên em nên sao chép code từ cửa sổ màu xám đầu
tiên vào chương trình của mình. Hãy tiếp tục và làm
điều đó."
Việc này thật dễ dàng. Erik nhanh chóng sao chép đoạn
text và dán nó bên dưới đoạn code hiện có.
"Bây giờ Mu yêu cầu em tạo một tệp mới," Simon tiếp
tục nói, "Sao chép đoạn text từ cửa sổ thứ hai và lưu nó
dưới dạng tệp mới 'greeting.html'"
Erik đã quen cách làm rồi. Cậu kích New trong Trình
chỉnh sửa Mu, xóa chương trình mà Mu vừa hiện ra rồi
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

sao chép đoạn text từ cửa sổ màu xám thứ hai. Tiếp đó,
cậu kích Save lưu dữ liệu lại.
Simon hỗ trợ cậu: "Sử dụng trình đơn thả xuống để thay
đổi từ '*.py' thành 'Other (*.*)', nếu không Mu sẽ nghĩ
rằng em đang cố lưu một chương trình Python. Chúng
ta nên nói với nó rằng lần này là một loại tệp khác. Tại
vị trí trường 'Save as', gõ greeting.html."

"Bây giờ dừng chương trình và chạy lại," Simon nói.


"Đừng quên chuyển sang tab 'first_app.py'."
Erik chuyển sang tab ứng dụng, kích vào nút Stop và ấn
Run lại. Cậu nhìn thấy kết quả tương tự ở dưới cùng của
cửa sổ.
"Bây giờ, hãy quay lại trình duyệt của em và làm theo
những gì nó gợi ý. Nhìn này, nó nói 'hãy truy cập /xin
chào/tên bạn' và bảo em sử dụng tên chính mình. Làm
theo đi, thêm /hello/Erik vào thanh địa chỉ, ngay sau số
5000."
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Bây giờ nó trông giống như hack thực sự. Erik nhập
những gì Simon gợi ý và nhấn ENTER.

"Wow! Nó nói chuyện với em này!" Cậu thực sự cảm


thấy ấn tượng.
"Chương trình đã sẵn sàng nói chuyện với em," Simon
nói. "Thật dễ dàng phải không?"
"Chờ em chút," Erik nói, "Nếu chúng ta định làm việc
trên cái trang web này, em cần gọi cho Emily. Bạn ấy nói
với em rằng bạn ấy đã học HTML và đây là thứ chúng ta
cần cho trang web, phải không anh?"
"Hoàn toàn chính xác," Simon đồng ý. "Gọi cho bạn ấy
đi. Làm việc cùng nhau bao giờ cũng tốt."
LƯỢT CỦA BẠN: Bạn hãy tạo ứng dụng web cá nhân
đầu tiên
Chuyển sang chế độ web trong Mu Editor và tạo ứng
dụng web đầu tiên bằng cách sao chép ví dụ từ trang

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của trình duyệt, giống như Erik đã làm. Hãy thử


chạy nó với tên của bạn. Hãy thử những cái tên
khác. Hiển thị nó cho bạn bè và bảo họ sử dụng tên
bản thân.

Emily sống gần đây và sau khoảng 15 phút cô nàng đến


một cách rất hào hứng. Cô hỏi ngay: "Erik, cho tớ xem
HTML của cậu!"
Erik cho cô ấy xem tệp hello.html và nói: "Chà, đó không
phải là code của tớ, nó từ Trình chỉnh sửa Mu này."

“Chà, thật thú vị,” Emily nói. "Tớ chưa bao giờ nhìn thấy
những dấu ngoặc nhọn này trong HTML."
"Phải đo" Simon nói, "Bởi vì đây không phải là HTML
thuần túy, nó là một dòng mẫu. Chúng ta dùng chương
trình có tên là Flask ở đây và nó sử dụng các mẫu
template để tạo HTML chung chung."
“Em hiểu,” Emily nói. "Với lại em biết các thẻ <h1> và
thẻ <p> này."
"Thẻ? 'Thẻ' là gì?" Erik hỏi.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Thẻ là những đoạn mã nhỏ này mà bạn đặt vào đoạn


text của mình để thay đổi giao diện của nó. Xem nè, bạn
đặt <h1> trước 'Xin chào!' và </h1> sau nó và nhìn nó
sẽ lớn hơn. Đây là thứ trong HTML được gọi là tiêu đề
header, giống như đề mục lớn của chương." "Còn <p>
thì sao?" Erik hỏi.
"Nó có nghĩa là 'đoạn văn'," Emily giải thích. "Trong
HTML, bạn có thể viết đoạn text theo cách bạn muốn:
trong một dòng dài hoặc nhiều dòng ngắn hoặc thậm chí
một từ trên mỗi dòng. Mà nếu nó có <p> ở đầu và </p>
ở cuối thì nó sẽ là một đoạn trong trình duyệt."
"Có rất nhiều thẻ khác nữa" Cô tiếp tục nói. "Bạn có thể
in đậm hoặc in nghiêng đoạn text của mình, thay đổi
màu sắc, v.v."
"Emily, em có biết gì về biểu mẫu HTML không?" Simon
hỏi.
“Thầy nói với bọn em trong lớp rằng bọn em có thể tạo
biểu mẫu trong HTML để nhập đoạn text hoặc sử dụng
menu,” Emily trả lời. "Nhưng bản thân em vẫn chưa thử
chúng."
"Menu là những gì chúng ta muốn!" Erik kêu lên.
“Anh sẽ giúp em,” Simon nói. "Đầu tiên, chúng ta nên sử
dụng các thẻ HTML bắt buộc. Chúng ta phải luôn có
<html> ở đầu tệp và </html> ở cuối. Ngoài ra, chúng ta
nên sử dụng các thẻ <body> bọc quanh đoạn text của
mình. Làm giống như trước, chúng ta sử dụng < body>
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

để mở đoạn text và </body> để đóng đoạn text. Đó là lý


do tại sao các thẻ có dấu gạch chéo / được gọi là thẻ
đóng."

“Chúng giống như các dấu ngoặc trong danh sách của
Python,” Erik nói. Cậu ấy muốn cho Emily biết rằng cậu
đã biết Python rồi.
“Em nói đúng,” Simon xác nhận. "Các thẻ này bao gồm
một số đoạn text và giải thích ý nghĩa của nó. Một số
đoạn đoạn text là tiêu đề, một số là đoạn văn. Nhưng bây
giờ chúng ta cần tạo menu. Để làm được điều đó, trước
tiên chúng ta cần thẻ <form> và sau đó là thẻ <select> ở
bên trong. Chúng ta cùng nhau tạo một menu rất đơn
giản nào" Rồi anh ấy bắt đầu viết.

LƯỢT CỦA BẠN: Bạn hãy tạo biểu mẫu web đầu tiên
Tạo tệp form.html và lưu với đường dẫn mu_code /
templates. Sao chép code trước đó và kiểm tra nó

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

trong trình duyệt của bạn. Thử thay đổi các tùy
chọn; thử thêm nhiều tùy chọn.

Simon viết xong, kích Save và lưu tệp dưới dạng


form.html trong thư mục mu_code/templates. "Hãy
nhìn xem, em thấy có bao nhiêu yếu tố elements được
đính kèm trong các thẻ ở đây? Emily, chắc em quen
thuộc hơn với cái này hơn."
Emily bắt đầu đếm. "Đầu tiên, thẻ <html>, sau đó là thẻ
<body>. Bên trong phần thân, chúng ta có một thẻ
<form> thì bên trong form ta có <select>. Nó dành cho
thực đơn, đúng không ạ? Và sau đó trong phần 'select',
chúng ta có hai phần tử <option>."
"Phải. Em nói đúng rồi, Emily," Simon nói. "Và cũng
đừng quên phần tử <input> là một phần của ‘form’. Nó
không có thẻ đóng. Nó chỉ tồn tại một mình. Chúng ta sử
dụng nó để tạo nút 'Submit'."
"Hãy xem nó trông như thế nào trong trình duyệt,"
Simon tiếp tục giảng giải.
"Anh có mở tệp trong trình duyệt được không?" Erik
hỏi. "Em nghĩ trình duyệt chỉ dành cho các trang web."
"Tất nhiên, bạn có thể làm được," Emily trả lời. "Bọn tôi
đã làm biết bao nhiêu lần trong lớp HTML của mình!
Bạn chỉ cần sử dụng menu File trong trình duyệt, sau đó
Open File..., sau đó tìm tệp của bạn và thế là xong."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik làm theo những gì Emily vừa nói và mở tệp


Forms.html. Cậu ấy nhìn thấy một menu, rất giống với
những gì cậu đã thấy và sử dụng trên nhiều trang web.
Cậu kích Click menu và nó mở ra:

"Tớ không biết rằng bạn có thể tạo các biểu mẫu dễ dàng
đến thế," Emily nói.
"Đúng, khá dễ dàng để tạo ra một biểu mẫu đơn giản
như thế này, nhưng vẫn còn thiếu một số phần," Simon
nói.
“Em thấy nó ổn mà” Erik nói. "Cái gì còn thiếu ạ?"
"Uh, trông thì tốt đấy, nhưng nó không làm được gì cả,"
Simon nói. "Chúng ta phải lấy dữ liệu từ người dùng và
sau đó truyền dữ liệu đó sang chương trình. Làm thế
nào chúng ta truyền được dữ liệu?" Simon hỏi, rồi tự trả
lời câu hỏi của chính mình. "Chúng ta nên sử dụng các
biến và giá trị, rất giống với Python. Hãy để anh thêm
một số thứ vào biểu mẫu này."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Simon tiếp tục giải thích


1. "Hãy nhìn vào số (1)," Simon nói. "Ở đây cần xác định
biến mà chúng ta muốn trả về từ menu. Trong menu
này, biến được gọi là drink.
2. "Bây giờ, trên dòng số (2) và dòng sau nó, chúng ta
xác định giá trị mà tùy chọn menu này sẽ trả về. Nó rất
giống với những gì chúng ta đã làm khi chọn các item từ
menu, nhớ không em?"
3. "Và trong dòng có số (3), anh vừa thêm một tùy chọn
cho người dùng biết phải làm gì. Tùy chọn này sẽ hiển
thị đầu tiên trong menu và hoạt động như một lời nhắc.
Như em thấy đấy, giá trị của nó trống. Nếu người dùng
chưa chọn đồ uống, chúng ta nên nói với họ rằng bạn
chưa chọn đồ uống. Em không thể chuẩn bị đơn đặt
hàng của họ nếu không có thông tin này, có đúng
không?"
"Em thử nó được chưa?" Erik hỏi.
"Tất nhiên, em thử nó đi và mở lại tệp này. Hoặc chỉ cần
tải lại tệp trong trình duyệt."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Erik tải lại tệp, chọn "Decaf" từ menu, kích vào "Send"
và nhận được như hình sau:

"Cái gì vậy?" Cậu hỏi, vẻ bối rối rõ ràng.


"Ồ, anh quên nói với em," Simon nói. "Nhìn nè, anh đã
thay đổi thẻ biểu mẫu form một chút."

"Mỗi form nên có một hành động," Anh bắt đầu giải
thích. "Hành động là điều mà ứng dụng của chúng ta
sẽ thực hiện khi người dùng submit biểu mẫu form.
Khi người dùng đưa ra lựa chọn của họ—cà phê hoặc
decaf—họ truyền thông tin này đến một số hàm. Hàm

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

đó sẽ biết phải làm gì với thông tin này: lưu trữ nó


trong tệp hoặc cơ sở dữ liệu, in đơn hàng, v.v."
"Giống hệt cái chúng ta đã làm trong chương trình
trước phải không?" Erik hỏi.
"Bạn cứ nói mãi về chương trình 'trước đây' của
mình, bạn cho tôi xem được không?" Emily yêu cầu.
“Anh xin lỗi, Emily,” Simon nói. "Đáng lẽ anh nên giải
thích sớm hơn. Bọn anh đã làm với Erik trong một
chương trình thu thập đơn đặt hàng trong quán cà
phê. Nó tương tự như Starbucks, chỗ em có thể gọi
đồ uống, thêm hương vị và toppings, v.v. Erik đã viết
một chương trình hiển thị thực đơn và hỏi khách
hàng họ muốn gọi món gì. Khi họ chọn drink, flavor
và toppings, chương trình sẽ in đơn hàng. Nhưng
chương trình hiện chỉ hoạt động trong một thiết bị
đầu cuối, ở chế độ đoạn text. Erik cần sự trợ giúp của
em để chuyển đổi nó thành một ứng dụng web." “Em
hiểu rồi,” Emily nói. "Đây có vẻ là một dự án tuyệt vời!
Em hy vọng Erik cũng sẽ dạy em Python."
“Tất nhiên rồi” Simon nói. "Dạy ai đó là cách tốt nhất
để học."
"Trở lại món form của chúng ta đi" Anh tiếp tục nói.
"Thuộc tính hành động đó cho trình duyệt biết: 'Sau
khi người dùng gửi biểu mẫu, hãy mở địa chỉ này và
truyền thông tin từ biểu mẫu form đến đó. Trong
trường hợp của chúng ta, địa chỉ được gọi là /order.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Đừng lo lắng, nó chỉ nghe có vẻ đáng sợ, Anh sẽ chỉ


cho em phải làm gì với nó," Simon nói thêm vì anh
nhận thấy sự bối rối trên khuôn mặt của Emily và
Erik.
“Em vẫn không hiểu,” Erik hỏi. "Địa chỉ mà anh đang
nói tới là ở đâu vậy?" "Hãy nhìn vào ứng dụng đầu
tiên của em," Simon nói. "Thấy hàm chào này không?"
“Hàm này được viết bởi Mu Editor cho chúng ta—hay
đúng hơn là các tác giả của nó,” Simon nói. "Bây giờ
em thấy định nghĩa hàm quen thuộc bắt đầu bằng def,
nhưng ngoài ra, ngay phía trên nó, em có thể thấy
một cái gì đó mới: @app.route('/hello/<name>').
Trong Python, nó được gọi là trình trang trí
decorator, nhưng hôm nay chúng ta sẽ không tìm
hiểu về decorators [Decorator là công cụ rất mạnh
mẽ và hữu ích trong Python vì nó cho phép các lập
trình viên sửa đổi hành vi của hàm hoặc lớp.
Decorator cho phép chúng ta nhận tham số đầu vào
là một hàm khác và mở rộng tính năng cho hàm đó
mà không thay đổi nội dung của nó].

Điều quan trọng đối với chúng ta ngày nay là em có thể


sử dụng nó để báo cho chương trình biết hàm nào sẽ sử
dụng cho địa chỉ nào."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"À ha, địa chỉ là /hello/Erik mà em đã nhập trong trình


duyệt, giờ em thấy rồi!" Erik nói. "Chúng ta cùng cho
Emily thấy nó hoạt động như thế nào đi" Rồi cậu ấy mở
tab có tập lệnh first_app.py trong trình chỉnh sửa, kích
Click Run rồi kích Browser. Trình duyệt của cậu ấy mở
ra một trang có lời chào từ Mu.
"Emily, nhìn này, tớ có thể gõ địa chỉ vào đây, ngay sau
những con số này: 127.0.0.1:5000 và xem nó cho chúng
ta thấy gì!" Erik gõ: /hello/Emily, nhấn ENTER và trình
duyệt hiển thị:

"Ồ, tớ thích nó rồi!" Emily nói. "Tớ thử được không?" và


cô sửa "Emily" thành "Erik". Tất nhiên, trình duyệt hiển
thị trang có nội dung "Xin chào Erik, bạn khỏe không?"
"Thật thú vị!" Cô nói. "Trong lớp HTML của bọn em, bọn
em có thể thay đổi các trang, nhưng bọn em phải chỉnh
sửa HTML. Điều này dễ dàng hơn nhiều!"
"Phải," Simon nói, "Đây là cái mà chúng ta gọi là các
trang động—các trang thay đổi tùy thuộc vào nội dung
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

bạn nhập. Em có thể nhập thông tin của mình vào địa
chỉ, như /hello/Emily hoặc em có thể sử dụng biểu mẫu
form. Sau đó, trang sẽ được được tạo bằng cách sử dụng
thông tin em đã nhập. Anh chắc rằng em đã thấy loại
trang này nhiều lần—ví dụ: khi em nhập nhận xét hoặc
trò chuyện với ai đó trên web. Em kích Click 'Submit'
hoặc chỉ cần nhấn ENTER và trang được cập nhật, phải
không? Bây giờ em sẽ học cách tự tạo những trang như
vậy."
"Để anh vẽ nó trên sơ đồ," Anh nói và bắt đầu vẽ

"Tổ hợp các chữ cái và số ở đầu trình duyệt của em được
gọi là 'địa chỉ' hoặc 'URL'. Anh đã đánh dấu nó bằng màu
xanh lam. Thông thường, em sẽ thấy tên của trang web
ở đây, chẳng hạn như google.com. Trong trường hợp

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của chúng ta, nó sử dụng các số được gọi là tên của trang
web Địa chỉ IP. Chúng ta sử dụng máy tính của riêng
mình và đối với mọi máy tính trên thế giới, địa chỉ
127.0.0.1 có nghĩa là 'máy tính này'. Nhưng đừng lo lắng
về điều đó bây giờ vội."
Simon chỉ vào vòng tròn màu đỏ đầu tiên xung quanh từ
‘order’ trong địa chỉ và nói: "Đây là điều chúng ta nên
quan tâm. Nhìn này, nó là một phần của địa chỉ. Khi mở
địa chỉ này, chúng ta sẽ thấy biểu mẫu form có menu đồ
uống. Khi em kích Submit,"thì nó theo mũi tên đi xuống
trong sơ đồ" biểu mẫu biết rằng nó sẽ tìm hàm chịu
trách nhiệm về địa chỉ /order. Em thấy đấy, nó ở đây,
trong trường form action.
Và sau đó "nó đi theo mũi tên đến khối 'Python'," biểu
mẫu tìm thấy hàm Python có thể hoạt động với nó, bởi
vì chúng ta đã sử dụng trình trang trí - decorator này,
@app.route('/order'). Em thấy đấy, ba thứ này được kết
nối với nhau; em chỉ cần sử dụng cùng một tên trong địa
chỉ, trong biểu mẫu và trong chương trình Python."
"Em thấy rằng hàm này cũng được gọi là ‘order’--có
phải là nơi thứ tư chúng ta sử dụng nó không?" Erik hỏi.
"Em thật tinh mắt!" Simon nói và mỉm cười. "Không
phải đâu, trong trường hợp này, hàm có thể có một tên
khác. Anh có thể gọi nó là 'new_order' hoặc 'get_order'.
Nhưng bây giờ chúng ta phải viết hàm thực sự. Anh sẽ
giúp em ở đây. Nó sẽ trông hơi đáng sợ, nhưng đừng lo.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Anh đang tự học hệ thống Flask này, vẫn thường làm


theo hướng dẫn trực tuyến và lấy các ví dụ từ đó. Đừng
nghĩ rằng anh tự nhớ tất cả những điều này."
Và Simon viết hàm này, nhìn vào ví dụ mà anh ấy đã mở
trong trình duyệt. Anh ấy đã thêm các con số vào cuối
các dòng để giúp anh ấy giải thích.
"Tại dòng (1), em thấy hai từ: 'GET' và 'POST'. Đây là các
phương thức chúng ta sử dụng với máy chủ web. Chúng
ta sử dụng GET khi muốn lấy thứ gì đó từ máy chủ web,
chẳng hạn như một trang web . Chúng ta sử dụng POST
để gửi một số thông tin đến máy chủ web. Giống như
trong trường hợp này—chúng ta muốn gửi hoặc POST
đồ uống do khách hàng chọn. Nói cách khác: khi em tải
một trang trong trình duyệt—em sử dụng GET; em kích
Click Submit trong form—em sử dụng POST. Em sẽ hiểu
rõ hơn khi chúng ta bắt đầu sử dụng nó, đừng lo lắng.
"Còn chỗ này, tại dòng có số (2), chúng ta dùng một từ.
Hãy xem nó nói gì: nếu phương thức là POST--có nghĩa
là ai đó đã điền vào form và kích Submit -chúng ta đọc
thông tin họ đã nhập vào biểu mẫu và in nó.
"Bây giờ hãy nhìn vào số (3). Hãy nhớ trong form chúng
ta đã dùng <select name="drink">? Đây là tên chúng ta
sử dụng ở đây, trong ngoặc vuông. Sau này, chúng ta sẽ
thêm các menu khác—cho flavor and toppings. Trong
biểu mẫu, chúng sẽ có các tên như 'flavour' và 'topping'.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Ở đây trong code, chúng ta sẽ sử dụng chúng dưới dạng


request.form['flavor'] và request.form['topping']."
"Số (4) bên dưới, chúng ta chỉ in bất cứ thứ gì chúng ta
nhận được từ biểu mẫu. Em sẽ thấy nó trong trình chỉnh
sửa.
"Ở dòng có số (5), chúng ta yêu cầu máy chủ web của
chúng ta in trang này cùng với menu. Nó giống như một
vòng lặp menu mà chúng ta dùng trong chương trình
của mình trước đây—em lấy thông tin từ khách hàng, in
ra và quay lại menu để nhận đơn hàng khác. Và em lặp
lại vòng lặp này cho đến khi nhập xong đơn hàng."

❶ Các phương thức mà chúng ta sẽ sử dụng với biểu


mẫu này
❷ Phương thức POST có nghĩa là chúng ta đang gửi
thông tin
❸ Chúng ta nhận được sự lựa chọn của khách hàng từ
trường của biểu mẫu có tên là đồ uống
❹ In lựa chọn chúng ta đã nhận được
❺ Hiển thị template mẫu forms.html
"Hãy để anh thêm một thứ nữa," Simon nói và thêm yêu
cầu vào dòng đầu tiên với import. "Modules này được
gọi là request là một phần của Flask. Nếu chúng ta sử
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

dụng nó, chúng ta phải import kéo nó vào." Bây giờ dòng
đầu tiên trông như thế này:

LƯỢT CỦA BẠN: Viết hàm order() của riêng bạn


Thêm hàm order() ở trên vào chương trình
first_app.py của bạn. Đừng quên thêm dòng import.
Thử chạy chương trình. Mở một tab mới trong trình
duyệt và sử dụng địa chỉ http://127.0.0.1:5000/order.
Nếu bạn gặp vấn đề, hãy tiếp tục đọc và làm theo
những gì Emily và Erik đang làm.

"Em có thể chạy nó ngay bây giờ không?" Erik hỏi anh.
Trông anh hơi mệt sau một lần giải thích dài thượt.
Emily đang đứng bên kia anh, đang lắng nghe những lời
giải thích của Simon như thể anh là một phù thủy. Cô ấy
thích tất cả phép thuật lập trình này và nóng lòng muốn
thử chương trình.
"Tớ chạy nó được không?" Emily hỏi.
“Tất nhiên là được” Erik nói. "Chỉ cần kích Save và sau
đó Run."
"Bây giờ bấm Duyệt," Simon nói.
Emily làm theo và trang tiếp theo được mở trong tab
trình duyệt mới.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Bây giờ chúng ta phải thêm /order vào địa chỉ, nhớ
chứ?" Simon giúp cô.
Emily làm theo và dòng địa chỉ trong trình duyệt
trở thành: http://127.0.0.1:5000/order.
Trang hiện ra menu thực đơn mà họ vừa cùng nhau tạo
ra.

"Tiếp đi, chọn drink và kích Submit" Simon nói.


Emily đã chọn Decaf và kích Submit. Cô nhận được
trong giống như menu 'Choose drink'.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nó có hoạt động không ạ?" Cô hỏi. Cô ấy trông có vẻ bối


rối.
"Nào chúng ta cùng kiểm tra" Simon nói. "Quay lại trình
chỉnh sửa. Nhìn vào phía dưới cửa sổ."

"Em có thấy dòng này không: Drink: decaf? Đó là những


gì chương trình của chúng ta đang in," Simon nói. "Điều
đó có nghĩa là nó đang hoạt động!"
"Nhưng em cho là," Emily nói, "Rằng nó sẽ in order trên
trang."
"Sẽ như thế, tin anh đi," Simon nói. "Chúng ta vẫn chưa
viết tới phần đó. Chúng ta đang đến đó, ngay bây giờ
đây."
Anh ấy lấy bàn phím và thay đổi tệp first_app.py bằng
cách thêm một dòng sau dòng print(). Simon giải thích:
"Khi chúng ta mở địa chỉ /order lần đầu tiên trong trình
duyệt, điều đó có nghĩa là chúng ta sử dụng phương
thức GET.
Chúng ta muốn lấy trang trước, phải không? Chúng ta
chưa có gì để POST cả. Trong trường hợp đó, chúng ta
dùng template mẫu form.html để hiển thị menu đồ uống

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

của chúng ta. Nhưng sau khi chúng ta đã chọn đồ uống


và kích Submit, chúng ta sử dụng phương thức POST.
Chúng ta muốn gửi thông tin này đến chương trình. Và
trong trường hợp đó, chúng ta thu thập dữ liệu từ biểu
mẫu form—lựa chọn đồ uống —và sử dụng một
template mẫu khác. Anh gọi nó là print.html vì chúng ta
muốn in đơn đặt hàng." Hàm order() bây giờ trông như
thế này:

“Nhưng chúng ta chưa có tệp có tên print.html,” Emily


nói.
"Được rồi, anh sẽ tạo nó ngay bây giờ," Rồi Simon tạo
một tệp khác trong trình chỉnh sửa và lưu nó dưới dạng
print.html trong templates mẫu.
Emily nhìn vào code của anh rồi nói: "Ồ, em hiểu cái này!
Anh in lề trên là 'Cảm ơn vì đơn đặt hàng của bạn' và
sau đó anh xuống dòng và in 'Đồ uống của bạn đây' rồi
tiếp là cho in đậm thức uống. Với drink này trong dấu
ngoặc nhọn hoạt động giống như kiểu hoạt động lúc tên
của em khi nó được in ra là 'Xin chào Emily', phải
không?"
"Chính xác rồi!" Simon kêu lên. "Em hoàn toàn đúng,
Emily!"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

LƯỢT CỦA BẠN: Chỉnh sửa biểu mẫu web của bạn
để in lựa chọn đồ uống trên trang
Sao chép mẫu ở trên vào tệp print.html của bạn. Vui
lòng thay đổi tiêu đề và đoạn text. Thay đổi
first_app.py bằng cách thêm dòng có return và lưu
nó. Thử chạy chương trình của bạn xem.

"Em có thể thử nó không?" Emily hỏi.


"Được chứ, em thử đi, hãy kích Run," Simon nói.
Emily kích Run, chọn "Cà phê" từ menu và thấy trang
như hình sau:

"Tuyệt, nó hoạt động rồi!" cô kêu lên.


“Nó giống như gọi hàm print_order() trong chương
trình trước của chúng ta,” Erik nói.
"Đúng chính xác!" Simon nói.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Nhưng làm cách nào để quay lại trang đặt hàng?" Erik
hỏi.
"Em nhìn này, địa chỉ trong trình duyệt vẫn trỏ đến
/order. Điều đó có nghĩa là nếu em kích dòng địa chỉ
bằng chuột và nhấn ENTER, em sẽ tải lại trang đặt hàng.
Chỉ cần không kích Click nút tải lại reload nếu không nó
sẽ tạo một đơn đặt hàng khác."
Emily làm theo lời Simon và xem lại trang đặt hàng.
“Nhưng có một cách tốt hơn,” Simon nói. "Em đang tìm
kiếm một nút trên trang in, chẳng hạn như Quay lại
trang đặt hàng, phải không?"
"Vâng, làm vậy sẽ dễ dàng hơn," Emily đồng ý.
"Chúng ta có thể sử dụng một form khác để làm vậy,"
Simon nói. "Nó đơn giản lắm" Rồi anh thêm vài dòng vào
tệp templates/print.html.
"Hãy nhìn xem, chúng ta đã tạo một biểu mẫu khác chỉ
có nút Submit. Chúng ta vừa đổi tên nó thành 'New
Order'. Em nhìn đi, nó trỏ đến /order trong trường hành
động của mình. Điều đó có nghĩa là khi chúng ta kích
Click nút 'New Order’ Đơn hàng mới, nó sẽ gửi chúng ta
đến trang /order. Rồi nó sẽ hiển thị lại menu đồ uống.
Hãy làm thử đi!"

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Emily làm theo và sau khi kích Submit, cô ấy thấy một


trang có nút mới.

Cô kích cái nút mới ấy và chương trình quay lại trang


đặt hàng.
Erik lưu ý: "Nó giống như menu chính của chúng ta mà
chạy vòng lặp. Đặt hàng, sau đó xác nhận, sau đó in, rồi
quay lại menu đặt hàng."
"Em nói đúng!" Simon xác nhận. "Hãy để anh trình bày
trên một sơ đồ."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Hãy nhìn vào sơ đồ. Bước một: em chọn Decaf từ menu.


Thao tác này sẽ gán giá trị decaf cho biến drink trong
form biểu mẫu."
"Bước hai: giá trị decaf đó được chuyển đến chương
trình Python của chúng ta thông qua request.form. Bây
giờ biến drink trong chương trình Python có giá trị
decaf."
"Bước ba: chúng ta chuyển giá trị của biến drink từ
Python—là decaf--đến biến drink trong template
print.html."
"Bước bốn: chúng ta gọi hàm render_template() với
biến drink được thay thế bằng giá trị của nó là decaf. Và
bây giờ decaf được in trên trang web."
"Cuối cùng, bước năm: chúng ta kích 'New order' và
quay lại trang đơn hàng."
LƯỢT CỦA BẠN: Thay đổi mẫu print.html
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Thêm nút 'New order’ Đơn hàng mới vào mẫu


templates/print.html. Thử chạy nó xem.
Bạn có quay lại trang đặt hàng được không?

"Emily và Erik, hôm nay các em đã làm rất tốt," Simon


nói. "Quan trọng nhất, em đã không ngủ gật trong tất cả
những lời giải thích dài dòng đó."
“Em gần như đã như vậy đấy” Erik nói.
“Đúng, anh có để ý thấy” Simon mỉm cười. "Nhưng
nghiêm túc mà nói, tạo ứng dụng web khó gấp 10 lần so
với làm việc trên menu đoạn text và hội thoại. Anh
ngưỡng mộ sự kiên nhẫn của em!"
“Nhưng nó đáng giá,” Emily nói. "Giờ thì chương trình
hoạt động rồi!"
“Chúng ta cũng cần thêm flavor and toppings,” Erik nói.
"Đúng rồi!" Simon hô to. "Chúng ta phải tạo tất cả các
menu nhưng ở dạng web. Anh khá chắc chắn rằng Emily
sẽ giúp em làm việc đó."
"Chắc chắn rồi," Emily nói, "Có vẻ như chúng ta cần
thêm nhiều select form cho template mẫu. Erik, bạn có
thể cho tớ xem chương trình trước đó của bạn không?
Chúng ta sẽ bắt đầu làm việc với ứng dụng web vào ngày
mai."
“Tất nhiên là được” Erik nói. "Chúng ta hãy gặp nhau
vào ngày mai và cùng làm việc."

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

"Anh rất sẵn lòng giúp," Simon nói. "Xin vui lòng cho anh
biết em bắt đầu lúc nào."

10.1 Những điều mới bạn học được hôm


nay

● Chế độ web trong Mu Editor


Ngoài chế độ Python tiêu chuẩn, trình soạn thảo Mu
còn có chế độ web. Nó có một ví dụ ứng dụng web đơn
giản.
● Biểu mẫu Forms HTML
Đây là một cách để lấy thông tin từ người dùng vào
một ứng dụng web. Chúng ta có menu, trường text,
nút. Khi chúng ta kích Submit, biểu mẫu sẽ gửi thông
tin đến một địa chỉ đặc biệt được định cấu hình trong
trường action. Từ địa chỉ đó, thông tin có thể được xử
lý bởi một chương trình.
● Flask
Một chương trình giúp chúng ta tạo các ứng dụng web.
Nó đang được phát triển bởi cộng đồng Mã nguồn mở,
nó có các hướng dẫn và ví dụ hay. Nó được sử dụng
bởi nhiều trang web trực tuyến và ứng dụng web.

10.2 Code cho chương này


Bạn có thể tìm thấy code cho chương này ở đây:
https://github.com/pavelanni/lets-talk-python-book/tree/main/ch10
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Ý tưởng cho ứng dụng đầu tiên của bạn

Tạo một ứng dụng quán cà phê trông không hấp dẫn
lắm đối với bạn phải không? Hãy tạo một cái gì đó khác!
Tất cả các ý tưởng và phương pháp lập trình mà chúng
ta thảo luận trong cuốn sách này đều có thể áp dụng cho
rất nhiều dự án khác. Chỉ cần nhìn xung quanh và bạn
sẽ có ý tưởng cho các ứng dụng khác.
Ví dụ:

A.1 Quán pizza


Ý tưởng này rất giống với những gì chúng ta làm với ứng
dụng quán cà phê. Xem này — chúng ta hỏi khách hàng:
● Thức uống chính của họ là gì?
● Hương vị họ muốn là gì? Topping là gì?

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Chúng ta cung cấp cho khách hàng một danh sách các
lựa chọn cho mỗi câu hỏi và khách hàng sẽ chọn từ
menu.
Chúng ta có nên hỏi khách hàng gì nữa ở tiệm bánh
pizza không?
● Bạn muốn loại vỏ bánh nào? Mỏng hay dày?
● Cỡ nào? Nhỏ, vừa hoặc lớn?
● Bạn muốn nước sốt nào? Đỏ hay trắng?
● Bạn muốn loại bánh pizza nào? Margherita,
pepperoni, veggie,… Hãy đến tiệm bánh pizza yêu thích
của bạn và xem họ có món gì.
● Bạn muốn thêm topping nào?

A.2 Quán kem


Đi đến cửa hàng kem yêu thích của bạn và xem họ chuẩn
bị đơn đặt hàng cho bạn như thế nào. Họ hỏi bạn điều
gì? Các lựa chọn họ cung cấp cho bạn là gì? Những thứ
đó sẽ có trong menu ứng dụng của bạn.
Khả năng lớn họ sẽ hỏi:
● Loại vỏ ốc quế? Ốc quế thường, ốc quế tô, ốc quế cốc?
● Lấy bao nhiêu muỗng kem?
● Hương vị gì?
● Có topping nào không?

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Ở đây, nó sẽ hơi khác so với những gì chúng ta đã làm


cho quán cà phê. Sau khi bạn hỏi "Lấy bao nhiêu
muỗng?" Bạn phải hỏi nhiều lần về hương vị. Hãy suy
nghĩ về nó: Bạn làm điều đó kiểu gì trong Python?
Gợi ý: trong Python có thế lấy hàm range() để dùng
trong vòng lặp for. Chúng tôi đã dùng nó trong menu
của mình. Hãy thử sử dụng nó để hỏi chính xác về
hương vị kem.

A.3 Các nhân vật tý hon LEGO


Bạn có một bộ sưu tập các nhân vật tý hon LEGO
minifigures và từng phần của chúng. Bạn muốn chỉ đạo
bạn bè của mình xây dựng một cái gì đó mới. Bạn sẽ hỏi
họ những câu hỏi nào và bạn sẽ đưa ra những lựa chọn
nào cho họ?
 Chọn hình đầu: mặt cười, mặt đeo kính râm, mặt có
râu,…
 Chọn mũ đội đầu: tóc đen, tóc vàng, mũ cứng, mũ
cảnh sát,…
 Chọn thân hình: thợ máy, cảnh sát, áo sơ mi thắt cà
vạt, áo phông,…
 Chọn chân: quần jean xanh, quần đùi xanh lá cây,
quần túi hộp màu nâu,…
 Chọn phụ kiện: kiếm, radio, búa, kính lúp,…

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Bạn có thể thêm các điều kiện đặc biệt vào ứng dụng của
mình. Ví dụ: nếu người bạn đã chọn mũ cảnh sát thì họ
không thể chọn gậy bóng chày làm phụ kiện. Hãy nghĩ
đến việc thêm điều kiện này vào menu của bạn.
Điều gì sẽ xảy ra nếu việc chọn các bộ phận một cách
ngẫu nhiên? Điều đó có thể tạo ra một số nhân vật mô
hình tý xíu vui nhộn. Bạn sẽ thêm tùy chọn ngẫu nhiên
vào menu của mình như thế nào? Làm thế nào để bạn
thực hiện nó?
Gợi ý: trong Python có một modules gọi là random ngẫu
nhiên. Bạn nhập nó bằng câu lệnh nhập ở đầu tập lệnh
của mình và sử dụng hàm choice(). Hàm đó hoạt động
như sau: bạn đưa cho nó một danh sách các lựa chọn và
nó chọn ngẫu nhiên một trong số chúng. Lần tới khi bạn
gọi nó, hàm sẽ chọn ngẫu nhiên một thứ khác (hoặc, có
thể, cùng một item—do nó là ngẫu nhiên mà!). Ví dụ:
tạo tập lệnh ngắn này và chạy thử nó. Trong tập lệnh
này, chúng tôi yêu cầu Python 5 lần chọn ngẫu nhiên
một item từ danh sách ba loại tóc.

Chạy tập lệnh này và bạn sẽ thấy một cái gì đó như thế
này:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Tất nhiên, trong trường hợp của bạn, danh sách sẽ khác
và sẽ có 5 lựa chọn ngẫu nhiên khác theo thứ tự khác.

A.4 Ý tưởng dự án khác


Bạn có ý tưởng dự án nào khác không? Hãy chia sẻ
chúng trong diễn đàn liveBook:
https://livebook.manning.com/book/lets-talk-python/discussion.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Cách cài đặt Mu Editor và

môi trường Python


B
Trong Phụ lục này, chúng tôi sẽ giải thích cách cài đặt
Python trên máy tính của bạn. Cách đơn giản nhất là cài
đặt trình soạn thảo lập trình có chứa Python trong đó.
Chúng tôi khuyên bạn nên cài đặt Mu Editor. Chúng tôi
sử dụng nó trong cuốn sách này để việc theo dõi các
cuộc đối thoại và hướng dẫn sẽ dễ dàng hơn.
Chúng tôi cũng sẽ cung cấp cho bạn các liên kết đến các
cách khác để cài đặt Python—bạn cũng có thể thử
chúng.

B.1 Mu Editor
1. Trong trình duyệt web của bạn, hãy mở trang
web của Mu Editor: https://codewith.mu/.
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

2. Kích Tải xuống (nút màu xanh lá cây), Bạn sẽ thấy


trang sau:

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

3. Kích Tải xuống theo hệ điều hành của bạn. Trình


duyệt sẽ tải xuống tệp cài đặt cho hệ điều hành của bạn.
● Đối với Windows, nó sẽ tải xuống tệp cài đặt cho
hệ điều hành của bạn.
● Đối với Windows, nó sẽ là tệp .msi.
● Đối với macOS, nó sẽ là tệp .dmg.
● Đối với Linux, nó sẽ là tệp .AppImage.
4. Kích Hướng dẫn dành cho hệ điều hành của bạn và
làm theo hướng dẫn.
5. Mở Mu Editor như cách bạn thường mở các ứng dụng
trong hệ điều hành của mình. Bạn đã sẵn sàng để làm
việc trên dự án cá nhân chưa!

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Bạn cũng có thể sử dụng Mu Editor để lập trình vi điều


khiển và chế tạo rô-bốt, nhưng đó là chủ đề của một
cuốn sách khác.

B.2 Thonny
Thonny là một trình soạn thảo Python tuyệt vời khác
được tạo ra dành cho người mới bắt đầu. Bạn có thể tìm
thấy nó ở đây:
https://thonny.org/

Ngay trên trang đầu tiên, bạn sẽ tìm thấy các trình cài
đặt cho Windows, macOS và Linux. Đối với Windows,
hãy tải xuống tệp .exe và chạy nó. Đối với macOS, hãy tải
xuống tệp .pkg và cài đặt nó. Đối với Linux, hãy chạy tập
lệnh được cung cấp trong hướng dẫn.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

Sau khi bạn cài đặt ứng dụng, hãy khởi động và hiển thị
các cài đặt của nó. Bạn có thể chọn màu nền từ khoảng
một tá lựa chọn, chọn phông chữ của trình soạn thảo và
thiết bị đầu cuối terminal, cùng nhiều thứ khác nữa.
Thonny có một tính năng rất hữu ích được gọi là Trợ lý.
Trong menu Option, bạn có thể định cấu hình để nó khởi
động mỗi khi có cảnh báo trong code của bạn. Thêm
nữa, nó ý kiến khi chương trình của bạn hiển thị lỗi.
Chức năng trợ lý cung cấp cho bạn một số gợi ý về lỗi có
thể xảy ra với code của bạn. Hãy thử mắc một lỗi nhỏ
Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình
Hãy nói về Python – Pavel Anni – ©Manning Publications Co.

trong code đi (ví dụ: lỗi đánh máy trong tên biến), sau
đó chạy chương trình và bạn sẽ thấy chức năng Trợ lý
hoạt động.

B.3 Python
Cả hai trình soạn thảo được mô tả ở trên đều bao gồm
Python trong các gói cài đặt của chúng. Nhưng vì một số
lý do, bạn có thể muốn cài đặt riêng Python.
Nếu bạn đang dùng macOS hoặc Linux, thì hệ điều hành
của bạn đã được cài đặt Python. Nhiều khả năng đó
không phải là phiên bản Python mới nhất, nhưng đó
không phải là vấn đề: tất cả các chương trình chúng tôi
phát triển trong cuốn sách này sẽ hoạt động với các
phiên bản Python bắt đầu từ 3.5. Không cần cài đặt bất
cứ thứ gì trên các hệ điều hành này—ít nhất là không
cho cuốn sách này.
Nếu bạn đang dùng Windows, bạn sẽ phải truy cập
trang web chính thức của Python:
https://www.python.org/downloads/windows/ và tải
xuống trình cài đặt từ đó.
Vui lòng đọc kỹ các ghi chú (xem ảnh chụp màn hình bên
dưới) và chọn đúng phiên bản Python cho hệ điều hành
Windows của bạn.

Chuyển ngữ: Nguyễn Tiến Thành – T.N.Trung | Trường THPT Khương Đình

You might also like