"
Em Học Python - Sách Hướng Dẫn Vui Học Lập Trình
🔙 Quay lại trang tải sách pdf ebook Em Học Python - Sách Hướng Dẫn Vui Học Lập Trình
Ebooks
Nhóm Zalo
Lời khen tặng dành cho
EM HỌC PYTHON
“Một cách hết sức tuyệt vời để kết nối cả gia đình.”
—Patrice Gans, Education Week
“Không hề thua kém gì sách hướng dẫn lập trình dành cho người lớn cả.” —Matthew Humphries, Geek.com
“Jason Briggs đã thực sự thành công khi mang thế giới lập trình đến cho trẻ em mà không hề phải giảm tải bớt nội dung. Các bài học được xây dựng rất tốt, đến mức khiến cho độc giả luôn có cảm giác đạt được thành công khi kết thúc mỗi chương.”
—Marziah Karch, blog GeekMom của Wired.com
“Cuốn sách rất lôi cuốn. Không có gì hơn là viết ra vài dòng code, hiện ra vài thứ gì đó lên màn hình và hiểu được mọi chuyện đã xảy ra như thế nào và tại sao lại như thế.” —Copil Yáñez, tạp chí Full Circle
“Một cẩm nang hướng dẫn lập trình dành cho bất cứ ai yêu thích lập trình, không phân biệt độ tuổi. Một tài liệu tham khảo tuyệt vời dành cho cả bố mẹ lẫn giáo viên.” —Roy Wood, GeekDad
“Tôi có hỏi cô con gái tám tuổi của mình nghĩ sao về “Em Học Python”. Cô bé nhất trí cho cuốn sách năm sao… Tôi rất vui khi thấy con viết ra những chương trình Python thật sự nhờ đọc từng trang sách.”
—Richard Bejtlich, Giám đốc An ninh ở Mandiant
“Một cuốn sách tuyệt vời cho bất cứ ai muốn theo học lập trình mà không bị choáng ngợp.” —Sandra Henry-Stocker, ITworld
EM HỌC PYTHON
SÁCH HƯỚNG DẪN
VUI HỌC LẬP TRÌNH
JASON R. BRIGGS
Phan Chương dịch (v1.0)
pltchuong@gmail.com
MỤC LỤC CHÍNH
Giới thiệu Tác giả, Hoạ sĩ minh hoạ và nhóm Tư vấn kỹ thuật . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Lời cảm ơn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Lời giới thiệu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
PHẦN I: LẬP TRÌNH CĂN BẢN
Chương 1: Không phải con gì trơn trơn cũng là rắn đâu nhé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Chương 2: Tính toán và biến trong lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Chương 3: Chuỗi, mảng, tuple và map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Chương 4: Vẽ vời với rùa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Chương 5: Đặt câu hỏi với if và else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Chương 6: Cùng đi lòng vòng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Chương 7: Tái sử dụng code với hàm và module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Chương 8: Cách sử dụng lớp và đối tượng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Chương 9: Các hàm Python được viết sẵn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Chương 10: Các module hay dùng trong Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Chương 11: Gặp lại đồ hoạ con rùa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Chương 12: Dùng tkinter để có đồ hoạ đẹp hơn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
PHẦN II: GAME BOUNCE!
Chương 13: Bắt đầu viết game Bounce! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Chương 14: Hoàn thiện game Bounce! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
PHẦN III: GAME MR. STICK MAN RACES FOR THE EXIT
Chương 15: Tạo các hình ảnh cho game Mr. Stick Man . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Chương 16: Bắt đầu lập trình game Mr. Stick Man . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Chương 17: Dựng hình nhân vật Mr. Stick Man . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Chương 18: Hoàn thiện game Mr. Stick Man . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Lời cuối: Làm gì tiếp theo đây . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Phụ lục: Tất cả từ khoá trong Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . 293 Chú giải . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Chỉ mục . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
MỤC LỤC CHI TIẾT
GIỚI THIỆU TÁC GIẢ, HOẠ SĨ MINH HOẠ VÀ
NHÓM TƯ VẤN KỸ THUẬT xv LỜI CẢM ƠN xvii LỜI GIỚI THIỆU xix
Sao lại là Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx Học lập trình như thế nào? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx Quyển sách này dành cho ai? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi Trong sách có những nội dung gì? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii Website của sách . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii Vui là chính! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
PHẦN I: LẬP TRÌNH CĂN BẢN
1
KHÔNG PHẢI CON GÌ TRƠN TRƠN CŨNG LÀ RẮN ĐÂU NHÉ 3
Tản mạn về ngôn ngữ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Cài đặt Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Cài đặt Python trên máy Windows 7 trở lên. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Cài đặt Python trên máy Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Cài đặt Python trên máy Ubuntu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 7 Làm gì sau khi cài Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Lưu lại chương trình Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2
TÍNH TOÁN VÀ BIẾN TRONG LẬP TRÌNH 13
Làm toán với Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Các toán tử trong Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Thứ tự tính toán . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Biến là mảnh giấy ghi chú . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Sử dụng biến . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Mục lục chi tiết 7
3
Chuỗi, mảng, tuple và map 23
Chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Khởi tạo chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Các vấn đề thường gặp với chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Ghép giá trị vào trong chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Dùng phép nhân trong chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Mảng còn khủng hơn chuỗi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Thêm phần tử vào mảng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Xoá phần tử trong mảng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Các phép toán với mảng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Python Maps không chỉ đường cho em đâu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
#1: Sở thích . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 #2: Đếm người . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 #3: Chào . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4
Vẽ vời với rùa 41
Sử dụng module turtle trong Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Tạo bảng vẽ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Di chuyển rùa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Tóm Tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 #1: Hình chữ nhật . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 #2: Hình tam giác . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 #3: Hộp mà không có góc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5
Đặt câu hỏi với if và else 51
Lệnh if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Khối lệnh là một khối các lệnh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Điều kiện là để so sánh mọi thứ với nhau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Lệnh if-then-else. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Lệnh if và elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Kết hợp các điều kiện . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Biến không có giá trị – None . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Sự khác biệt giữa chuỗi và số . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8 Mục lục chi tiết
Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 #1: Mình có giàu không ta? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 #2: Bánhhhhh! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 #3: Vừa đúng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 #4: Chiến đấu với ninja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6
Cùng đi lòng vòng 65
Vòng lặp for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Và nhân tiện đang nói về vòng lặp... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
#1: Chào gì chào lắm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 #2: Số chẵn số lẻ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 #3: Món ăn yêu thích . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 #4: Cân nặng trên mặt trăng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7
Tái sử dụng code với hàm và module 79
Dùng hàm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Các thành phần trong một hàm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Biến và phạm vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Dùng module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
#1: Hàm tính cân nặng trên mặt trăng cấp I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 #2: Hàm tính cân nặng trên mặt trăng cấp II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 #3: Chương trình tính cân nặng trên Mặt trăng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
8
Cách sử dụng lớp và đối tượng 89
Chia mọi thứ ra thành lớp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 Lớp con và lớp cha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 Tạo đối tượng từ lớp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Viết hàm cho lớp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Dùng hàm để mô tả các đặc trưng của lớp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Nhưng mà ta cần lớp với đối tượng để làm gì? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Đối tượng và lớp trong đồ hoạ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Vài thứ hay ho khác của lớp và đối tượng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Thừa kế hàm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Mục lục chi tiết 9
Hàm này gọi hàm kia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Khởi tạo đối tượng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
#1: Hươu chân trước đá chân sau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 #2: Rùa hình cái xiên . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
9
Các hàm Python được viết sẵn 107
Cách dùng các hàm được viết sẵn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Hàm abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Hàm bool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Hàm dir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Hàm eval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Hàm exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Hàm float . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Hàm int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Hàm len . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Hàm max và hàm min. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Hàm range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Hàm sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Làm việc với file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Tạo file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Mở file trong Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Ghi ra file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 #1: Đoạn code bí ẩn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 #2: Thông điệp bí mật . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 #3: Sao chép file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
10
Các module hay dùng trong Python 127
Tạo các bản sao với module copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Ghi nhớ các từ khoá với module keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Lấy số ngẫu nhiên từ module random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Dùng randint để chọn một số ngẫu nhiên. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Dùng choice để chọn phần tử ngẫu nhiên trong mảng . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 Dùng shuffle để trộn lẫn một mảng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Điều khiển shell với module sys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Dùng exit để thoát ra khỏi Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
10 Mục lục chi tiết
Đọc dữ liệu với đối tượng stdin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Ghi dữ liệu với đối tượng stdout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Mình đang dùng Python bản nào vậy ta? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Làm việc với thời gian bằng module time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Chuyển đổi ngày tháng với asctime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Lấy ngày tháng và thời gian với localtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Làm thời gian chậm lại với sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Lưu lại dữ liệu bằng module pickle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 #1: Nhân bản xe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 #2: Đóng gói danh sách yêu thích . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
11
Gặp lại đồ hoạ con rùa 145
Bắt đầu với hình vuông . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Vẽ hình ngôi sao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Vẽ hình xe ô tô . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Tô màu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Viết hàm để vẽ hình tròn có màu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Màu đen và màu trắng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Hàm để vẽ hình vuông . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Vẽ hình vuông có màu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Vẽ ngôi sao có màu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 #1: Vẽ hình bát giác . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 #2: Vẽ hình bát giác có màu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 #3: Lại một hàm vẽ ngôi sao nữa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
12
Dùng tkinter để có đồ hoạ đẹp hơn 167
Tạo nút nhấn nhấn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Tham số chỉ định . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Tạo bảng vẽ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Vẽ đường thẳng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Vẽ hình hộp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Vẽ thật nhiều hình hộp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Và thêm màu sắc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Vẽ hình cung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Vẽ hình đa giác . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Mục lục chi tiết 11
Viết chữ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Chèn ảnh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Tạo các chuyển động . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Tạo các tương tác . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Các trường hợp khác cần dùng số hiệu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
#1: Phủ tam giác kín màn hình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 #2: Tam giác động đậy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 #3: Hình ảnh động đậy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
PHẦN II: GAME BOUNCE!
13
BẮT ĐẦU VIẾT GAME BOUNCE! 205
Đập bóng bay lung tung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Tạo bảng vẽ cho game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Tạo lớp Ball . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Thêm vài hành động . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Làm bóng di chuyển . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Làm bóng bật tường . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Điều hướng bóng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
14
HOÀN THIỆN GAME BOUNCE! 217
Thêm thanh đỡ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Di chuyển thanh đỡ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Phát hiện va chạm giữa bóng và thanh đỡ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Thêm yếu tố thắng thua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Tóm tắt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Bài tập lập trình . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
#1: Hoãn thời gian khởi động game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 #2: “Game over” đúng nghĩa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 #3: Tăng tốc độ của bóng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 #4: Tính điểm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
12 Mục lục chi tiết
GIỚI THIỆU TÁC GIẢ
Jason R. Briggs học lập trình từ năm tám tuổi, anh bắt đầu với ngôn ngữ BASIC trên chiếc máy tính TRS-80 cũ kỹ của Radio Shack. Sau đó, anh trở thành lập trình viên và kỹ sư thiết kế hệ thống, đồng thời làm Cộng tác viên thường xuyên của tờ Java Developer’s Journal. Các bài viết của anh còn được đăng trên các tạp chí JavaWorld, ONJava, và ONLamp. Em học Python là cuốn sách đầu tay của anh.
Các em có thể liên lạc với tác giả Jason qua trang web http://jasonrbriggs.com/ hoặc gửi email cho anh ở địa chỉ mail@jasonrbriggs.com.
GIỚI THIỆU HOẠ SĨ MINH HOẠ
Miran Lipovača là tác giả cuốn Learn You a Haskell for Great Good!. Sở thích của anh là đấm bốc, chơi ghita bass, và tất nhiên là cả vẽ vời nữa. Anh rất mê mấy bộ xương biết nhảy múa, thích số 71, và mỗi khi bước qua mấy cái cửa tự động anh thường giả vờ là mình đang điều khiển bằng siêu năng lực.
GIỚI THIỆU NHÓM TƯ VẤN KỸ THUẬT
Josh Pollock, 15 tuổi, vừa tốt nghiệp cấp hai ở trường The Nueva và chân ướt chân ráo vào cấp ba ở trường Lick-Wilmerding, thành phố San Francisco. Lần đầu tiên cậu học lập trình là với Scratch năm 9 tuổi, sau đó là học ngôn ngữ TI-BASIC năm lớp 6, chuyển sang Java và Python năm lớp 7 rồi UnityScript năm lớp 8. Ngoài lập trình, cậu thích chơi kèn trumpet, viết game, và thích nói về các chủ đề khoa học kỹ thuật.
Maria Fernandez là thạc sĩ ngôn ngữ học ứng dụng, đam mê máy tính và công nghệ từ hơn 20 năm nay. Cô dạy tiếng Anh cho hội phụ nữ tị nạn trong khuôn khổ dự án Global Village ở bang Georgia, hiện đang sống ở khu vực phía bắc bang California và làm việc cho tổ chức giáo dục phi lợi nhuận ETS (Educational Testing Service).
LỜI NGƯỜI DỊCH
Tôi ấn tượng với cuốn sách này ngay từ lần đầu đọc, từ cách hành văn, từng câu chữ, cho đến những câu đùa, và tất nhiên là cả lượng kiến thức lập trình không nhiều nhưng cũng không hề ít được tác giả đề cập đến. Ngôn ngữ gần gũi và tếu táo của tác giả làm tôi nảy ra ham muốn nhất thời không kìm được, đó là dịch quyển sách này ra cho các độc giả nhỏ tuổi ở Việt Nam. Tôi luôn thấy thương các em với những lịch học dày đặc và những áp lực vô hình trên vai. Tôi hy vọng, thật sự rất hy vọng cuốn sách này sẽ mang đến cho các em niềm vui và, khơi dậy sự tò mò trong các em, để rồi các em có thể tự mở ra cho mình cánh cửa đến sự tự do và niềm vui được tự mình khám phá.
Python là một ngôn ngữ lập trình hết sức phổ biến trong những năm gần đây. Không những thế, nó còn là một trong những công cụ hiện đại nhất để bước chân vào kỷ nguyên của dữ liệu, xác suất và trí tuệ nhân tạo. Nghe thì phức tạp nhưng nó lại rất dễ tiếp cận, dễ nắm bắt, xứng đáng là ngôn ngữ lập trình dành cho mọi người.
Học lập trình, nói cho cùng, không phải là để thành lập trình viên. Lập trình về cơ bản cũng chỉ là một kỹ năng sống, một kỹ năng quan trọng!
Cuối cùng, bản dịch chắc chắn còn rất nhiều thiếu sót, bạn đọc vui lòng góp ý tại đây https://padlet.com/pltchuong/gop_y_ebook_em_hoc_python.
Seattle, tháng 1 năm 2021
Phan Chương
LỜI CẢM ƠN
Thử hình dung lúc bước lên sân khấu nhận giải thưởng, em phát hiện ra danh sách những người mình định nói lời cảm ơn bỗng nhiên không cánh mà bay: Em đảm bảo sẽ quên ai đó, để rồi chưa gì nhạc đã xập xình nổi lên mời em về chỗ.
Thế cho nên, đây là một danh sách (chắc chắn) không hoàn chỉnh những người tôi mang mối nợ ân tình sâu sắc, những người đã làm cho cuốn sách được như ngày hôm nay.
Xin gửi lời cảm ơn nhóm No Starch, đặc biệt là Bill Pollock, trong lúc biên tập đã bơm cho tôi không biết bao nhiêu liều “trẻ-con-sẽ-nghĩ-gì”. Một khi đã làm lập trình viên trong một thời gian dài, ta thường quên phéng mất là với những ai mới học những thứ này khó hiểu như thế nào, và những gì bị bỏ sót, những gì quá phức tạp mà Bill chỉ ra thực sự là vô giá. Xin cảm ơn Serena Yang, vị giám đốc sản xuất phi thường; rất hy vọng chị không phải bị rụng quá nhiều tóc chỉ để đảm bảo hơn 300 trang code được tô màu đúng chuẩn.
Xin chân thành cảm ơn những bức hình minh họa xuất sắc của Miran Lipovača. Còn hơn cả xuất sắc nữa ấy chứ. Thật đấy! Nếu để tôi minh họa, chắc phải may mắn lắm ta mới có một bức hình nhòe nhoẹt không ra ngô ra khoai gì. Là gấu à ...? Hay là chó ...? Khoan, từ từ, chỗ này phải là cây chứ?
Xin cảm ơn đội tư vấn kỹ thuật. Tôi rất áy náy vì vài ý kiến của các bạn cuối cùng cũng không được sử dụng. Các bạn có lý của mình, nên nếu có bất cứ sai sót gì thì tôi cũng chỉ có thể đổ lỗi cho sự khiếm khuyết của tính cách cá nhân tôi. Đặc biệt cảm ơn Josh đã có những đóng góp đáng kể, nhất là những lần bắt lỗi vô cùng chính xác. Và xin lỗi Maria vì thỉnh thoảng phải làm việc với những đoạn code không được đẹp mắt lắm.
Cảm ơn vợ và con gái, đã thông cảm với ông chồng và ông bố suốt ngày cắm mũi vào máy tính.
Cảm ơn Mẹ đã động viên con không biết bao nhiêu lần trong từng ấy năm.
Cuối cùng, cảm ơn Bố đã mua cho con cái máy tính từ những năm 1970 và cho phép con dùng nó thoải mái. Không có Bố, những chuyện thế này sẽ không bao giờ xảy ra.
Học lập trình để làm gì?
Lập trình thúc đẩy sự sáng tạo, suy luận và giải quyết vấn đề. Là một lập trình viên, em có cơ hội để nhào nặn ra cái gì đó từ hai bàn tay trắng, sử dụng tư duy logic để biến những dòng lệnh rời rạc thành một chương trình máy tính chạy được, làm việc được, và vận dụng tư duy sửa chữa vấn đề nếu mọi thứ chạy không đúng như kỳ vọng. Lập trình thực ra rất vui, có lúc hơi khó (và thỉnh thoảng hơi đâu-cái-điền1), bù lại những gì em học được từ đó sẽ rất có ích ở trường và đi làm... kể cả nếu công việc của em sau này không liên quan gì đến máy tính cả.
Và cuối cùng, chiều chiều trời tự nhiên xầm xì u ám mà ngồi lập trình thì còn hơn cả tuyệt vời!
1 Điên-cái-đầu
Lời giới thiệu 19
SAO LẠI LÀ PYTHON?
Python là ngôn ngữ rất dễ học và có những đặc điểm rất phù hợp với ai mới học lập trình. So với những ngôn ngữ khác thì Python khá là dễ đọc, và còn có một giao diện tương tác để viết và chạy code trên đó luôn rất tiện. Bên cạnh cấu trúc ngôn ngữ đơn giản, Python còn có vài thứ đặc biệt nữa giúp đẩy nhanh quá trình học tập, như là ghép những hình ảnh hoạt hình đơn giản riêng lẻ thành một game hoàn chỉnh. Một trong số đó là một module có tên turtle, lấy cảm hứng từ những hình ảnh của dự án Turtle (được sử dụng trong ngôn ngữ lập trình Logo tít từ những năm 1960 cơ) và module này được thiết kế riêng cho mục đích dạy và học. Một ví dụ khác là tkinter, module dùng để tương tác với bộ công cụ Tk, giúp ta có thể viết ra các chương trình có đồ họa và hình ảnh hoạt hình phức tạp hơn.
HỌC LẬP TRÌNH NHƯ THẾ NÀO?
Như tất cả những lần-đầu-tiên học gì đó, ta sẽ bắt đầu với những thứ hết sức đơn giản, cho nên hãy đọc từ những chương đầu tiên và phải thật cố gắng đừng nôn nóng bỏ qua để nhảy đến các chương sau. Không ai có thể chơi nhạc hay như nghệ sĩ ngay từ lần đầu tiên cầm nhạc cụ cả. Mấy chú học viên phi công cũng phải nắm được các thao tác điều khiển cơ bản trước khi lái máy bay thật. Còn các vận động viên thể hình (thông thường) cũng sẽ không thực hiện những cú nhảy lộn ngược ngay trong những lần thử đầu tiên đâu. Nếu em nhảy cóc quá nhanh, không những kiến thức cơ bản sẽ không nằm lại trong đầu, mà em sẽ thấy những kiến thức về sau tự nhiên khó hơn bình thường.
Thử viết lại từng ví dụ một trong lúc đọc, em sẽ thấy và hiểu nó hơn. Hầu hết ở cuối mỗi chương đều có vài bài tập lập trình để em thử và nâng cao kỹ năng. Nhớ là càng nắm chắc những kiến thức cơ bản thì về sau em càng dễ tiếp thu những bài học khó hơn.
20 Lời giới thiệu
Khi gặp cái gì đó quá khó hoặc quá đánh đố, tôi hay thử mấy cách sau:
1. Tách vấn đề ra thành từng phần nhỏ. Cố gắng hiểu từng đoạn code có tác dụng gì, hoặc là chỉ để tâm vào một phần nhỏ của cả vấn đề lớn (tức là tập trung vào một đoạn code ngắn thôi, thay vì cố hiểu tất cả cùng một lúc).
2. Nếu vẫn không ăn thua, thì tạm thời kệ nó. Ngủ một giấc rồi quay lại sau. Cách này có thể giải quyết được rất nhiều vấn đề, và đặc biệt có ích với lập trình viên.
QUYỂN SÁCH NÀY DÀNH CHO AI?
Quyển sách này dành cho bất cứ ai có hứng thú với lập trình máy tính, dù là trẻ em hay người lớn lần đầu học lập trình. Nếu muốn học cách để viết ra phần mềm của riêng mình thay vì cứ phải dùng phần mềm của người khác, thì cuốn Em Học Python này là điểm khởi đầu khá phù hợp.
Trong các chương tiếp theo, ta sẽ học cách cài đặt Python, mở Python shell và làm các phép tính đơn giản, in chữ ra màn hình, tạo mảng, điều khiển luồng với lệnh if và vòng lặp for (tất nhiên là sẽ phải học xem lệnh if và vòng lặp for là gì rồi!). Ta sẽ học cách làm sao để tái sử dụng code bằng cách dùng hàm, học những kiến thức căn bản về lớp và đối tượng, và mô tả sơ lược về các hàm và module có sẵn trong Python.
Sẽ có các chương về module turtle của Python từ đơn giản đến phức tạp, và các bài hướng dẫn sử dụng module tkinter để có thể đồ họa trên màn hình máy tính. Các bài tập với các độ khó khác nhau ở cuối mỗi chương để em tự viết các chương trình nhỏ sẽ giúp củng cố các kiến thức vừa mới học được.
Sau khi đã xây dựng được những kiến thức nền tảng về lập trình, em sẽ học cách tự viết game. Em sẽ dựng hai game liền, có đồ họa đàng hoàng. Và cũng sẽ học về cơ chế phát hiện va chạm, về các sự kiện, và về các kỹ thuật xây dựng hình ảnh động khác nhau.
Đa số các ví dụ trong sách dùng Python shell hay còn gọi là IDLE (Môi trường tích hợp dành cho Nghiên cứu và Phát triển ⟨Integrated Development and Learning
Lời giới thiệu 21
Environment⟩). IDLE có hỗ trợ hiển thị cú pháp, hỗ trợ chép và dán chữ (tương tự như cách em dùng các chương trình khác), và một cửa sổ soạn thảo để em có thể lưu lại code về sau còn dùng lại, nói tóm lại IDLE vừa là nơi thử nghiệm trực tiếp, vừa giống một trình soạn thảo code. Tất cả các ví dụ đều chạy được với các giao diện dòng lệnh cũng như các chương trình soạn thảo code, nhưng IDLE với khả năng hiển thị cú pháp và giao diện dễ dùng sẽ giúp em học hiểu nhanh hơn, do đó ngay chương đầu tiên ta sẽ học cách cài đặt nó.
TRONG SÁCH CÓ NHỮNG NỘI DUNG GÌ?
Dưới đây là vài dòng tóm tắt nội dung của từng chương cho em:
Chương 1 là lời mở đầu về lập trình cùng với các hướng dẫn để cài đặt Python.
Chương 2 giới thiệu về tính toán và biến trong lập trình, Chương 3 nói về các kiểu dữ liệu cơ bản trong Python như chuỗi, mảng, tuple và map.
Chương 4 em sẽ lần đầu tiên sử dụng module turtle. Ta sẽ nhảy từ lập trình cơ bản sang di chuyển rùa (trong hình dáng một cái mũi tên) quanh màn hình.
Chương 5 nói về các dạng khác nhau của lệnh if, Chương 6 nói về vòng lặp for và vòng lặp while.
Chương 7 ta bắt đầu viết và sử dụng hàm, Chương 8 học về lớp và đối tượng. Ta chỉ học vừa đủ các kiến thức và kỹ thuật cơ bản để phục vụ cho các chương sau khi viết game. Từ đây, nội dung học và thực hành sẽ bắt đầu phức tạp hơn một chút.
Chương 9 lướt qua hầu hết các hàm có sẵn trong Python, Chương 10 tiếp nối với vài module cũng được cài đặt sẵn cùng với Python (đại khái là một mớ các hàm hay dùng ấy mà).
22 Lời giới thiệu
Chương 11 quay trở lại module turtle vì lúc này em đã có kinh nghiệm với các hình phức tạp hơn. Chương 12 chuyển sang module tkinter để tạo ra các hình ảnh chuyển động khó hơn.
Trong Chương 13 và 14, ta sẽ viết game đầu tiên, “Bounce!,” dựa trên những kiến thức được học từ đầu đến giờ, và từ Chương 15 đến 18 ta sẽ viết một game khác nữa, “Mr. Stick Man Races for the Exit.” Trong các chương về lập trình game này, sẽ có những lúc em hoàn toàn mất phương hướng. Trong trường hợp đó, em có thể tải code từ website của sách (http://python-for-kids.com/) để so sánh với code của mình.
Ở Lời cuối, ta sẽ kết thúc bằng việc tham khảo PyGame và một vài ngôn ngữ lập trình phổ biến khác.
Cuối cùng, em sẽ học rất chi tiết về các từ khóa của Python trong phần Phụ lục, còn mục Chú giải sẽ liệt kê ra định nghĩa của các thuật ngữ lập trình được dùng trong suốt cả quyển sách.
WEBSITE CỦA SÁCH
Nếu em cần giúp đỡ gì đó trong lúc đang đọc sách, hãy thử vào website http://python-for-kids.com/, ở đây em có thể tải về tất cả ví dụ trong sách và nhiều bài tập lập trình khác. Em cũng có thể tìm thấy lời giải cho tất cả bài tập trong sách trên website, trong trường hợp bí quá hoặc đơn giản là chỉ muốn tự kiểm tra kết quả xem có đúng không.
VUI LÀ CHÍNH!
Lập trình rất vui, hãy cứ nhớ vậy trong lúc dò dẫm đi hết quyển sách. Đừng nghĩ đây là bài tập hay công việc gì cả. Hãy coi lập trình là để tạo ra game hoặc phần mềm gì đó vui vui hay hay mà em có thể mang đi khoe với bạn bè và mọi người xung quanh.
Học lập trình là một cách luyện tập trí não rất tuyệt và kết quả nó mang lại là không thể chối cãi. Nhưng cái quan trọng nhất là cho dù học được gì đi nữa, hãy nhớ, vui là chính!
Lời giới thiệu 23
24 Lời giới thiệu
Không phải con gì trơn trơn cũng là rắn đâu nhé 1
2 Chương 1
Mỗi chương trình máy tính là một tập hợp các chỉ dẫn để máy tính thực hiện một việc gì đó. Chúng không phải là thứ xung quanh máy tính như ta hay thấy – như dây dợ, bộ vi xử lý, các thẻ cắm, ổ cứng, đại loại thế – mà là thứ chạy ngầm trên những thiết bị đó. Mỗi chương trình máy tính, thường thì ta sẽ chỉ gọi là một chương trình ⟨program⟩, là một tập hợp các lệnh để chỉ đạo đống phần cứng vô dụng kia làm việc này việc nọ. Phần mềm ⟨software⟩ chính là một tập hợp các chương trình máy tính.
Không có các chương trình máy tính, hầu hết các thiết bị em đang sử dụng hàng ngày sẽ không còn hoạt động nữa hoặc không còn hữu dụng như nó vốn có nữa. Các chương trình máy tính, với nhiều kiểu rất khác nhau, không chỉ điều khiển mỗi cái máy tính em đang dùng, mà còn điều khiển cả máy chủ video game, điện thoại di động, thậm chí cả các hệ thống định vị toàn cầu trên ôtô nữa. Phần mềm cũng điều khiển những thứ ít hiển nhiên hơn như TV tinh thể lỏng và cả cái điều khiển TV nữa, cũng như những radio thế hệ mới, đầu đĩa DVD, bếp và cả tủ lạnh luôn. Rồi thì động cơ ôtô, đèn giao thông, đèn đường, đèn báo tàu hoả, biển quảng cáo hay thang máy cũng đều được điều khiển bởi phần mềm.
Không phải con gì trơn trơn cũng là rắn đâu nhé 3
Phần mềm ít nhiều giống như suy nghĩ vậy. Nếu không
suy nghĩ, ta có lẽ chỉ biết ngồi dưới đất, đăm chiêu nhìn vào
khoảng không trước mắt, miệng chảy dãi lòng thòng. Ý nghĩ
“đứng dậy nào” như là một hướng dẫn, một mệnh lệnh, yêu cầu
cơ thể ta phải đứng dậy. Tương tự như thế, phần mềm sẽ nói
cho máy tính biết phải làm gì.
Một khi đã biết viết ra các chương trình máy tính, em có
thể làm ra nhiều thứ rất hấp dẫn. Tất nhiên, em sẽ không thể viết ra các chương trình để điều khiển ôtô, đèn giao thông hay tủ lạnh được (ít nhất bây giờ thì chưa), nhưng em có thể tạo ra website, tự viết game, hoặc là viết ra một chương trình làm hộ bài tập về nhà cũng được.
TẢN MẠN VỀ NGÔN NGỮ
Máy tính cũng giống như con người, sử dụng các ngôn ngữ khác nhau để giao tiếp – trong trường hợp này ta gọi là ngôn ngữ lập trình. Ngôn ngữ lập trình ⟨programming language⟩ chỉ đơn giản là một cách thức cụ thể để nói chuyện với máy tính – một cách thức chỉ dẫn mà cả người lẫn máy đều hiểu.
Có những ngôn ngữ lập trình mang tên người (như Ada và Pascal), có cái lại là tên viết tắt (như BASIC hay FORTRAN), thậm chí có vài ngôn ngữ được đặt theo tên chương trình TV, như Python. Đúng thế đấy, ngôn ngữ lập trình Python được đặt theo chương trình TV Monty Python’s Flying Circus, chứ không phải python theo tiếng Anh là con rắn đâu.
CHÚ Ý
Monty Python’s Flying Circus là một chương trình hài được phát trên TV vào những năm 1970, và một vài khán giả tới tận giờ vẫn còn hết sức hâm mộ. Chương trình có những buổi diễn độc đáo như “The Ministry of Silly Walks,” “The Fish-Slapping Dance,” and “The Cheese Shop”.
4 Chương 1
Có nhiều thứ trong Python khiến cho nó trở thành một ngôn ngữ lập trình cực kỳ dễ tiếp cận đối với ai mới học. Điều quan trọng nhất là em có thể dùng Python để viết ra các chương trình máy tính hết sức đơn giản mà hiệu quả trong thời gian siêu ngắn. Trong Python không có quá nhiều ký tự phức tạp như các ngôn ngữ khác, điều này khiến nó trở nên dễ đọc và dễ học hơn. (Cũng phải nói rõ là Python có sử dụng ký tự đặc biệt đấy nhé — chỉ là không chi chít như các ngôn ngữ khác thôi.)
CÀI ĐẶT PYTHON
Cài đặt Python khá dễ. Ta sẽ đi qua các bước hướng dẫn để cài trên máy từ Windows 7 trở lên, Mac OS X, và Ubuntu. Khi cài Python, em đồng thời cũng sẽ cài đặt chương trình IDLE (Môi trường tích hợp dành cho Nghiên cứu và Phát triển ⟨Integrated Development and Learning Environment⟩), chính là nơi để em viết code Python. Nếu máy đã có sẵn Python, em có thể chuyển luôn sang mục “Làm Gì Sau Khi Cài Python” ở trang 9.
CÀI ĐẶT PYTHON TRÊN MÁY TỪ WINDOWS 7 TRỞ LÊN
Để cài đặt Python trên các máy từ Microsoft Windows 7 trở lên, tải Python bản từ 3.5 trở lên dành cho Windows ở đây http://www.python.org/downloads/.
CHÚ Ý
Khi tải, số phiên bản chính xác không quan trọng, miễn là từ bản 3.5 trở lên là được. Khi trình duyệt hỏi có muốn lưu lại file không thì chọn lưu lại.
Không phải con gì trơn trơn cũng là rắn đâu nhé 5
Sau khi tải bộ cài cho Windows về, thường thì máy sẽ hỏi em có muốn chạy bộ cài không. Nếu nó không hỏi, em có thể vào thư mục Downloads và nháy đúp vào bộ cài. Em cứ làm theo hướng dẫn trên màn hình để cài với các thông số mặc định thôi:
1. Nhấn Install Now.
2. Nếu được hỏi có cho phép chương trình lưu lại thay đổi trên máy không, chọn YES. 3. Cài xong thì chọn Close, lúc này em sẽ thấy có mục Python 3.5 trong menu Start của Windows:
Giờ em có thể bắt đầu học Python ở mục “Làm Gì Sau Khi Cài Python” ở trang 9. CÀI ĐẶT PYTHON TRÊN MÁY MAC OS X
Đầu tiên em sẽ phải cài đặt một phần mềm phụ trợ tên là ActiveTcl:
1. Vào trang https://www.activestate.com/products/tcl/downloads/, đăng ký một tài khoản miễn phí và tải ActiveTcl bản mới nhất về, nhớ chọn đúng bản cho Mac OS X. 6 Chương 1
2. File tải về sẽ có đuôi là .pkg. Nháy đúp vào file, rồi nháy đúp vào file ActiveTcl trong cửa sổ vừa mở ra. Làm theo hướng dẫn trên màn hình để cài đặt, chấp nhận điều khoản sử dụng và cài đặt với các thông số mặc định thôi. Em có thể sẽ phải điền mật khẩu máy tính lúc bắt đầu cài. Nếu không có mật khẩu thì hỏi bố mẹ nhé.
Đúng ra là em sẽ có sẵn Python trên máy Mac rồi, nhưng có thể chỉ là phiên bản cũ. Để chắc chắn đã có bản mới nhất, vào trang http://www.python.org/downloads/ để tải bộ cài đặt mới nhất:
Tải về rồi thì nháy đúp vào (tên file đại khái như python-3.5.0-macosx10.6.pkg), chấp nhận điều khoản sử dụng rồi cứ làm theo hướng dẫn trên màn hình để cài đặt thôi. Em có thể sẽ phải điền mật khẩu một lần nữa đấy.
Giờ em có thể bắt đầu học Python ở mục “Làm Gì Sau Khi Cài Python” ở trang 9. CÀI ĐẶT PYTHON TRÊN MÁY UBUNTU
Python được đi kèm cùng với bản phân phối Ubuntu của Linux, nhưng em sẽ phải cài thêm IDLE để có thể làm theo các hướng dẫn trong sách:
Không phải con gì trơn trơn cũng là rắn đâu nhé 7
1. Nhấn vào biểu tượng Show Applications (là biểu tượng có 9 dấu chấm thường nằm ở góc dưới bên trái màn hình)
2. Gõ chữ terminal vào ô tìm kiếm rồi ấn vào biểu tượng Terminal 3. Nhập mấy dòng lệnh sau vào cửa sổ Terminal, gõ từng dòng một nhé: sudo apt-get update
8 Chương 1
sudo apt-get íntall idle3
4. Em sẽ phải điền mật khẩu máy tính lúc chạy mấy lệnh này. Nếu không có mật khẩu thì hỏi bố mẹ nhé.
Thế là em đã có Python bản mới nhất trên máy rồi, chạy thử thôi.
LÀM GÌ SAU KHI CÀI PYTHON?
Cài Python xong rồi, ta sẽ thử viết chương trình đầu tiên trên IDLE nhé. Nếu dùng Windows, nhấn vào menu Start, nhập idle vào ô tìm kiếm, chọn IDLE (Python 3.5). Nếu dùng Mac, từ menu của Finder chọn Go ► Applications, mở thư mục Python 3.5 và tìm IDLE. Nếu dùng Ubuntu, menu Applications ► Programming sẽ có một mục tên là IDLE (using Python 3.5) hoặc mới hơn. Mở IDLE ra em sẽ thấy một cửa sổ trông như thế này
Không phải con gì trơn trơn cũng là rắn đâu nhé 9
Cửa sổ này được gọi là Python shell, là một phần của IDLE. Ba dấu lớn hơn (>>>) được gọi là dấu nhắc ⟨prompt⟩, là dấu hiệu chương trình đã sẵn sàng.
Giờ hãy gõ vài thứ vào dấu nhắc, bắt đầu với lệnh sau:
>>> print("Hello World")
Nhớ là phải có cặp ngoặc kép (" ") đấy nhé. Nhấn ENTER sau khi gõ xong. Nếu gõ lệnh đúng, em sẽ nhìn thấy kết quả như thế này:
>>> print("Hello World")
Hello World
>>>
Dấu nhắc sẽ lại hiện lên để em biết Python đã sẵn sàng
cho lệnh tiếp theo.
Giỏi quá! Em vừa mới viết được chương trình Python
đầu tiên rồi. Từ print là một lệnh trong Python được gọi là hàm
⟨function⟩, và nó sẽ in bất cứ cái gì được viết bên trong dấu
ngoặc ra màn hình. Nói cách khác, em vừa mới đưa máy tính
một mệnh lệnh là in chữ Hello World ra màn hình – một lệnh
mà cả em lẫn máy tính đều hiểu được.
LƯU LẠI CHƯƠNG TRÌNH PYTHON
Nếu mỗi lần muốn dùng một chương trình Python nào đó mà lại phải viết code hết lại từ đầu thì nghe hơi phiền, và đừng có nói là em đang nghĩ đến việc in ra giấy đấy nhé. Đương nhiên, mấy chương trình bé bé viết lại cũng được thôi, nhưng một chương trình phức tạp – kiểu xử lý văn bản chẳng hạn – có thể dài đến cả hàng triệu dòng code đấy. In hết ra chắc hơn 100.000 trang vẫn còn là ít. Cứ hình dung em phải khiêng đống giấy tờ đấy về nhà nhỉ. Đừng có mà để cơn gió nào thổi qua nhé.
10 Chương 1
Rất may, ta có thể giữ lại những chương trình này để về sau dùng lại. Để lưu lại một chương trình, mở IDLE và chọn File ► New Window. Một cửa sổ mới sẽ xuất hiện với tiêu đề *Untitled*. Nhập đoạn code sau vào cửa sổ shell mới đó:
print("Hello World")
Sau đó chọn File ► Save. Khi được hỏi tên file thì điền
vào hello.py và lưu lại file vào màn hình desktop. Tiếp đó
chọn Run ► Run Module.
Nếu làm đúng hết, chương trình em lưu lại sẽ chạy ngon lành như thế này:
Giờ em hãy đóng cửa sổ shell nhưng giữ lại cửa sổ hello.py và chọn Run ► Run Module, Python shell sẽ lại hiện ra, chương trình của em lại có thể chạy một lần nữa. (Nếu chỉ muốn mở Python shell mà không có chương trình nào chạy thì chọn Run ► Python Shell.)
Sau khi chạy, em sẽ nhận ra trên màn hình desktop của em có một file mới tên là hello.py. Nếu nháy đúp vào file đó, một cửa sổ đen đen sẽ nháy lên một cái rồi biến mất. Chuyện gì vậy chài?
Không phải con gì trơn trơn cũng là rắn đâu nhé 11
Thực ra em vừa mới nhìn thấy cửa sổ Python console (khá giống với Python shell) bật lên, in ra chữ Hello World và rồi tắt đi luôn. Nếu có đôi mắt thần nhìn thấy những thứ bay siêu nhanh, thì em sẽ thấy cửa sổ này ngay trước khi nó đóng:
Ngoài cách dùng menu ra, em cũng có thể dùng các phím tắt để tạo ra shell mới, lưu file và chạy chương trình:
● Trên Windows và Ubuntu, dùng CTRL-N để mở cửa sổ shell mới, dùng CTRL-S để lưu file lại sau khi viết code xong, và nhấn F5 để chạy chương trình.
● Trên Mac OS X, dùng ⌘-N để mở cửa sổ shell mới, dùng ⌘-S để lưu file lại, và giữ phím Fn cùng với F5 để chạy chương trình.
TÓM TẮT
Trong chương này ta đã cùng nhau viết chương trình Hello World – một chương trình hết sức đơn giản mà gần như ai học lập trình cũng phải viết. Trong các chương sau ta sẽ dùng Python shell để làm thêm nhiều thứ thú vị nữa nhé.
12 Chương 1
Cài đặt xong Python và biết bật Python shell lên là em đã sẵn sàng rồi đấy. Ta sẽ bắt đầu với một vài tính toán đơn giản và sau đó chuyển sang biến. Biến trong lập trình ⟨variable⟩ là một cách để ghi lại các thứ trong một chương trình máy tính, nhờ đó ta mới có thể viết được các chương trình có ý nghĩa.
LÀM TOÁN VỚI PYTHON
Thông thường, khi được bảo làm phép nhân hai số với nhau ví dụ 8 × 3.57, em sẽ lôi máy tính hoặc giấy bút ra để tính phải không nào. Giờ sao không dùng Python shell để làm phép tính này? Thử nhé.
Bật Python shell lên như hướng dẫn trong Chương 1, sau đó nhập biểu thức sau vào chỗ dấu nháy:
>>> 8 * 3.57
28.56
Tính toán và biến trong lập trình 13
Ta thấy là khi làm phép nhân trong Python, ta sử dụng dấu sao (*) thay cho dấu nhân (×).
Giờ thử làm hẳn một bài toán có ý nghĩa đàng hoàng nhé.
Giả sử vào một ngày đẹp trời, em đang đào xới gì đó ngoài vườn, bỗng nhiên đào được một cái túi đựng 20 đồng vàng. Em chạy ngay xuống hầm, nhét hết chỗ xu vào cái máy siêu-photocopy của ông nội đang phủ đầy bụi để dưới đó (may vừa đủ chỗ để nhét cả 20 xu). Em nghe tiếng máy chạy ù ì loạch xoạch, vài tiếng sau nó nhả ra thêm 10 đồng xu mới toanh.
Hỏi, nếu ngày nào cũng làm thế trong vòng một năm liền, em sẽ có bao nhiêu xu tất cả? Trên giấy, các phương trình sẽ kiểu như thế này:
10 × 365 = 3650
20 + 3650 = 3670
Tất nhiên là làm mấy phép tính này trên máy tính hoặc trên giấy thì quá dễ rồi, nhưng ta cũng có thể làm y như thế trên Python shell. Đầu tiên, nhân 10 xu với 365 ngày một năm để được 3650. Tiếp, ta cộng 20 xu ban đầu vào để được 3670.
>>> 10 * 365
3650
>>> 20 + 3650
3670
Xong tự nhiên có một con quạ phát hiện ra mấy đồng xu lấp lánh trong phòng, thế là tuần nào nó cũng lượn vào trộm mất ba xu. Hỏi, đến cuối năm em còn lại bao nhiêu xu?
Các phép tính trên shell sẽ trông như thế này:
>>> 3 * 52
156
>>> 3670 - 156
3514
14 Chương 2
Đầu tiên, ta nhân 3 xu với 52 tuần trong năm. Kết quả là 156. Lấy tổng số xu ta có (3670) trừ đi số đó sẽ được 3514 xu còn lại vào cuối năm.
Đây chỉ là một chương trình rất đơn giản. Trong quyển sách này, em sẽ học cách làm sao mở rộng những kiến thức này để viết ra những chương trình có ý nghĩa hơn.
CÁC TOÁN TỬ TRONG PYTHON
Em có thể làm các phép cộng, trừ, nhân, chia trong Python shell, cùng với những phép tính khác nữa mà ta sẽ tạm thời chưa nói tới. Các dấu được Python dùng để tính toán này được gọi là các toán tử ⟨operator⟩, được liệt kê ở Bảng 2-1.
Bảng 2-1: Các toán tử cơ bản trong Python
Dấu
Phép tính
+
Cộng
-
Trừ
*
Nhân
/
Chia
Dấu gạch chéo ⟨forward slash⟩ (/) được dùng cho phép chia vì
nó giống với dấu gạch khi ta viết phân số. Giả sử nếu ta có 100 tên cướp biển và 20 cái thùng lớn, giờ muốn biết mỗi thùng có thể giấu được bao nhiêu tên cướp biển thì em sẽ phải chia 100 tên ra 20 thùng (100 ÷ 20) bằng cách nhập 100 / 20 vào Python shell. Nhớ là dấu gạch chéo này nghiêng về phía bên phải nhé.
THỨ TỰ TÍNH TOÁN
Trong lập trình, ta sẽ dùng các dấu ngoặc tròn để điều khiển thứ tự tính toán. Cứ cái gì mà dùng toán tử thì đều gọi là phép tính ⟨operation⟩. Phép nhân và phép chia được xếp
Tính toán và biến trong lập trình 15
hạng cao hơn phép cộng và phép trừ, nghĩa là được ưu tiên hơn. Nói cách khác, khi em viết ra một biểu thức trong Python, các phép nhân và phép chia sẽ được tính trước phép cộng và phép trừ.
Ví dụ, trong biểu thức sau, số 30 và 20 sẽ được nhân với nhau trước, sau đó 5 mới được cộng vào tích trên.
>>> 5 + 30 * 20
605
Nếu dùng từ ngữ để diễn đạt biểu thức này thì sẽ là, “nhân 30 với 20, lấy kết quả cộng với 5”. Kết quả là 605. Ta có thể thay đổi thứ tự của các phép tính bằng cách ngoặc hai số đầu tiên lại như thế này:
>>> (5 + 30) * 20
700
Kết quả của biểu thức này là 700 (không phải 605 nữa) vì
dấu ngoặc sẽ yêu cầu Python tính bên trong trước, sau đó mới
đến lượt các phép tính bên ngoài. Ví dụ này sẽ được diễn đạt lại
là “cộng 5 với 30, sau đó nhân kết quả với 20.”
Các dấu ngoặc có thể lồng vào nhau ⟨nested⟩, nghĩa là có
thể có ngoặc trong ngoặc, như thế này:
>>> ((5 + 30) * 20) / 10
70.0
Trong trường hợp này, Python sẽ tính nội dung ở trong ngoặc trong cùng, rồi tính dần ra ngoài, cuối cùng mới đến phép chia. Nói cách khác, biểu thức được diễn đạt là “cộng 5 với 30, nhân kết quả với 20, lấy kết quả mới chia cho 10.” Và thứ tự diễn ra sẽ là:
● Lấy 5 cộng 30 được 35.
● Lấy 35 nhân 20 được 700.
● Lấy 700 chia cho 10 để có kết quả cuối cùng là 70.
16 Chương 2
Nếu không có ngoặc, kết quả sẽ hơi khác đi một chút:
>>> 5 + 30 * 20 / 10
65.0
Lúc này, đầu tiên 30 sẽ nhân với 20 (được 600), rồi 600 chia cho 10 (được 60). Cuối cùng sẽ cộng với 5 để ra kết quả là 65.
CHÚ Ý
Hãy nhớ rằng phép nhân và phép chia luôn được tính trước phép cộng và phép trừ, trừ khi có dấu ngoặc can thiệp vào thứ tự tính toán.
BIẾN LÀ MẢNH GIẤY GHI CHÚ
Biến trong lập trình ⟨variable⟩ được dùng để lưu các thông tin như số, chữ hoặc mảng nhiều số, mảng nhiều chữ, vân vân và mây mây. Em có thể coi biến như một mẩu giấy ghi chú có viết các thông tin trên đó.
Ví dụ, để tạo ra biến fred, ta sẽ dùng dấu bằng (=) và nói Python ta muốn ghi lại thông tin gì lên tờ giấy kia. Ở đây, ta tạo ra biến fred và nói Python hãy viết số 100 lên (chú ý là các biến khác nhau vẫn có thể có giá trị giống nhau đấy nhé):
>>> fred = 100
Để kiểm tra xem một biến ghi lại thông tin gì trên đó, gõ print vào shell, rồi gõ tên biến vào trong một cặp ngoặc đơn như thế này:
>>> print(fred)
100
Ta cũng có thể bảo Python thay đổi biến fred để nó mang thông tin gì đó khác đi. Ví dụ để đổi fred thành số 200:
>>> fred = 200
>>> print(fred)
200
Tính toán và biến trong lập trình 17
Dòng đầu tiên, ta bảo fred ghi lại con số 200. Dòng thứ hai, ta hỏi fred hiện đang giữ thông tin gì, để kiểm tra lại cho chắc. Python sẽ in kết quả ra ở dòng cuối cùng
Ta cũng có thể có nhiều mảnh giấy như thế (tức là nhiều biến) cho cùng một thông tin giống nhau:
>>> fred = 200
>>> john = fred
>>> print(john)
200
Trong ví dụ này, ta bảo Python rằng ta muốn biến john lưu cùng thông tin y như biến fred bằng cách dùng dấu bằng giữa john và fred.
Ở đây, rõ ràng đặt tên biến là fred nghe chẳng ăn nhập gì, vì về cơ bản nó không nói cho ta biết biến này lưu trữ cái gì cả. Ta sẽ đổi tên biến từ fred sang number_of_coins như thế này:
>>> number_of_coins = 200
>>> print(number_of_coins)
200
Giờ thì ai cũng hiểu là ta đang nói về 200 xu rồi nhé.
Tên biến có thể được viết bằng chữ cái, số và ký tự gạch dưới (_), nhưng không bắt đầu bằng số được. Em có thể dùng bất cứ gì từ một ký tự duy nhất (a chẳng hạn) cho đến cả một câu dài ngoằng để làm tên biến. (Vì tên biến không thể có khoảng trắng nên ta dùng dấu gạch dưới thay cho dấu cách.) Đôi khi, khi đang làm gì đó nhanh nhanh chóng chóng, dùng tên biến ngắn gọn là phù hợp nhất. Tên biến mà em chọn thường phụ thuộc vào việc em cần nó có có ý nghĩa đến mức nào.
18 Chương 2
SỬ DỤNG BIẾN
Còn nhớ mấy biểu thức em dùng để tính xem cuối năm em sẽ có bao nhiêu xu nếu dùng phát minh kỳ diệu của ông nội đang để dưới hầm để đẻ ra xu mới không? Mấy biểu thức này này:
>>> 20 + 10 * 365
3670
>>> 3 * 52
156
>>> 3670 - 156
3514
Ta có thể biến chúng thành một dòng biểu thức duy nhất:
>>> 20 + 10 * 365 – 3 * 52
3514
Giờ ta sẽ chuyển mấy con số bên trên thành biến như này:
>>> found_coins = 20
>>> magic_coins = 10
>>> stolen_coins = 3
Mấy dòng này sẽ tạo ra các biến found_coins (số xu nhặt được), magic_coins (số xu mới được tạo ra từ máy) và stolen_coins (số xu bị mất).
Thay vào biểu thức trên ta có:
>>> found_coins + magic_coins * 365 - stolen_coins * 52
3514
Ơ vẫn ra cùng kết quả kìa, thế thì
nói làm gì? À ha, sức mạnh ma thuật của
biến chính là ở đây. Giả sử trên cửa sổ
giờ có một con bù nhìn, con quạ thấy thế
sợ quá chỉ trộm được hai xu thay vì ba xu
Tính toán và biến trong lập trình 19
thì sao? Một khi đã tạo ra biến, ta có thể thay đổi để nó có giá trị mới, và bất cứ chỗ nào dùng biến đó sẽ được thay đổi theo. Ta có thể thay đổi giá trị của biến stolen_coins sang 2 như sau:
>>> stolen_coins = 2
Sau đó ta có thể chép và dán biểu thức bên trên để tính lại, như thế này:
1. Bôi đen dòng cần chép bằng cách nhấn chuột trái và kéo từ đầu dòng đến cuối dòng như hình dưới đây:
2. Giữ phím CTRL (hoặc nếu đang dùng Mac thì giữ phím ⌘) rồi nhấn C để chép dòng vừa được bôi đen. (Từ giờ ta sẽ gọi là CTRL-C cho ngắn ngọn.)
3. Nhấn chuột vào dấu nhắc cuối cùng (ngay sau stolen_coins = 2)
4. Giữ phím CTRL và nhấn V để dán dòng đã được chép. (Từ giờ ta sẽ gọi là CTRL-V.) 5. Nhấn ENTER để có kết quả mới:
20 Chương 2
Thế có phải là đỡ hơn nhiều so với gõ lại toàn bộ biểu thức không? Rõ rồi còn gì.
Em có thể thử thay đổi các biến khác, rồi chép (CTRL-C) và dán (CTRL-V) lại biểu thức trên để thấy kết quả thay đổi như thế nào. Giả sử em căn thời gian chính xác rồi đá cái máy một phát, máy sẽ nhả ra thêm 3 xu mỗi lần chạy, cuối năm em sẽ có tổng cộng 4661 xu:
>>> magic_coins = 13
>>> found_coins + magic_coins * 365 - stolen_coins * 52
4661
Đương nhiên, sử dụng biến trong những biểu thức đơn giản kiểu này thì mới chỉ có tác dụng tí tẹo thôi. Chưa đến mức cực kỳ có tác dụng. Nhưng giờ em chỉ cần nhớ rằng biến là một cách để ghi lại mọi thứ để về sau còn dùng lại.
TÓM TẮT
Trong chương này. em đã thấy cách sử dụng các toán tử trong Python để thực hiện các tính toán đơn giản và cách dùng ngoặc để điều khiển thứ tự các phép tính (là thứ tự mà Python sẽ dựa theo đó mà tính toán từng phần của biểu thức). Sau đó ta tạo ra biến để ghi lại các giá trị rồi sử dụng lại chúng trong các phép tính.
Tính toán và biến trong lập trình 21
22 Chương 2
Chương 2 đã nói về các tính toán cơ bản và về biến trong lập trình Python. Chương này ta sẽ nói về vài thứ khác trong lập trình Python bao gồm: chuỗi, mảng, tuple và map. Chuỗi được dùng để hiển thị các câu các chữ trong chương trình (kiểu như mấy chữ “Get Ready” và “Game Over” trong game ý). Mảng, tuple và map được dùng để lưu nhiều thứ với nhau cùng một lúc.
CHUỖI
Trong lập trình nói chung ta thường gọi chữ là chuỗi ⟨string⟩. Em cứ hình dung chuỗi giống như là một danh sách các ký tự liền nhau vậy, cho dễ nhớ. Tất cả chữ cái, con số, ký hiệu trong quyển sách này đều có thể là chuỗi. Không chỉ thế đâu, tên em cũng là chuỗi này, địa chỉ nhà cũng là chuỗi nốt. Thực ra, ngay chương trình Python đầu tiên ta viết từ Chương 1 cũng đã dùng chuỗi rồi: “Hello World.”
Chuỗi, mảng, tuple và map 23
KHỞI TẠO CHUỖI
Trong Python, chuỗi được tạo ra bằng cách lồng các câu vào
trong một cặp ngoặc đơn hoặc ngoặc kép (Ta phải làm thế để bảo
máy tính đây là số, kia là chữ, kiểu vậy). Lấy ví dụ ta có thể dùng lại biến fred ở Chương 2 để ghi lại một chuỗi như này:
>>> fred = "Why do gorillas have big nostrils? Big fingers!!" Sau đó để xem bên trong fred có gì, ta có thể gõ print(fred) như này:
>>> print(fred)
Why do gorillas have big nostrils? Big fingers!!1
Em cũng có thể dùng dấu ngoặc đơn để tạo chuỗi đấy nhé:
>>> fred = 'What word is always spelled wrong in the dictionary? Wrong!!'
>>> print(fred)
What word is always spelled wrong in the dictionary? Wrong!!2
Nhưng mà, nếu câu của em có nhiều hơn một dòng mà chỉ sử dụng dấu ngoặc đơn (') hoặc ngoặc kép ("), hoặc là nếu em mở bằng ngoặc này và đóng bằng ngoặc kia thì em sẽ gặp lỗi trên Python shell ngay. Thử nhập dòng sau mà xem:
>>> fred = "Why do birds fly?
Kết quả:
SyntaxError: EOL while scanning string literal
Lỗi này nói rằng cú pháp câu lệnh không chính xác, vì em đã phá luật không đóng ngoặc ở cuối chuỗi.
Cú pháp ⟨syntax⟩ là sự sắp xếp theo đúng thứ tự của từng chữ trong một câu, hoặc như trong trường hợp này thì là sự sắp xếp theo đúng thứ tự của các từ khóa và ký hiệu trong một chương trình. Vậy SyntaxError nghĩa là em đã làm gì đó không đúng thứ tự
1 Câu đùa: “Sao lỗ mũi đười ươi to quá vại? Vì ngón tay nó to!!” (ngoáy nhiều thành ra lỗ mũi to ^^) 2 Câu đùa: “Trong từ điển chữ nào luôn luôn bị viết sai? Chữ Sai!!”
24 Chương 3
khiến Python không hiểu, hoặc là Python đang cần gì đó mà em lại không viết ra. EOL là viết tắt của hết dòng ⟨end-of-line⟩, vậy toàn bộ lỗi nói rằng Python đã đọc hết dòng lệnh rồi mà vẫn không tìm thấy dấu đóng ngoặc ở cuối chuỗi.
Để một chuỗi có thể chứa nhiều hơn một dòng chữ (còn gọi là chuỗi nhiều dòng ⟨multiline string⟩), em có thể dùng ba dấu ngoặc đơn ('''), rồi nhấn ENTER để sang dòng như thế này:
>>> fred = '''Why do birds fly?
It's faster than walking!'''
In nội dung của fred ra thử xem sao:
>>> print(fred)
Why do birds fly?
It's faster than walking!3
CÁC VẤN ĐỀ THƯỜNG GẶP VỚI CHUỖI
Có một ví dụ này rất rối rắm, viết kiểu gì cũng bị bắn ra lỗi:
>>> silly_string = 'He said, "Aren't can't shouldn't wouldn't."' SyntaxError: invalid syntax
Ở đây ta đang tạo ra một chuỗi (với biến silly_string), được bọc lại bởi hai dấu ngoặc đơn ở hai đầu, nhưng bản thân chuỗi lại có mấy từ cũng có dấu ngoặc đơn là can't, shouldn't, wouldn't, xong ở giữa lại còn có mấy dấu ngoặc kép nữa. Hỗn hết cả loạn!
Em phải hiểu Python không thông minh như người đâu, nên cái nó thấy chỉ là chuỗi này thôi He said, "Aren, sau đó là một đống những ký tự thừa thãi gì đâu. Mỗi khi Python nhìn thấy một dấu ngoặc (bất kể là ngoặc đơn hay ngoặc kép), là nó tự hiểu sau dấu ngoặc đó sẽ là chuỗi, thế là nó cứ thế đi cho đến hết dòng để tìm dấu ngoặc còn lại (ngoặc đơn hoặc ngoặc kép tương ứng). Trong trường hợp này, chuỗi được bắt đầu ở dấu ngoặc đơn nằm trước từ He, và kết thúc ở dấu ngoặc đơn ở sau chữ n trong Aren, Python chỉ biết có vậy. IDLE có đánh dấu ngay tại điểm mà mọi thứ trở nên sai sai:
3 Câu đùa: “Vì sao chim lại bay? Vì bay nhanh hơn đi bộ chứ sao!”
Chuỗi, mảng, tuple và map 25
Dòng cuối của IDLE giải thích đại khái em đang gặp lỗi gì – trong trường hợp này là một lỗi cú pháp.
Thay bằng dấu ngoặc kép vào cũng không giải quyết được vấn đề gì:
>>> silly_string = "He said, "Aren't can't shouldn't wouldn't."" SyntaxError: invalid syntax
Lần này, Python phát hiện ra một chuỗi được bọc bởi hai dấu ngoặc kép, chứa các ký tự He said, (và một dấu cách). Tuốt tuồn tuột những thứ còn lại (tính từ Aren't trở đi) chính là tác nhân gây lỗi:
Đó là do, dưới góc nhìn của Python, tất cả những gì thừa thãi đều không nên tồn tại. Nó đi tìm dấu ngoặc tiếp theo để kết thúc chuỗi và hoàn toàn không hiểu em muốn nó làm gì với mấy thứ hầm bà lằng nhằng sau dấu đóng ngoặc đó.
Giải pháp cho tình huống này là dùng chuỗi nhiều dòng mà ta vừa học được bằng cách sử dụng ba dấu ngoặc đơn ('''), như vậy, ta có thể kết hợp cả ngoặc đơn lẫn ngoặc kép mà không gặp vấn đề gì. Đúng hơn là, một khi đã bọc bằng ba dấu ngoặc đơn, ta có thể
26 Chương 3
dùng bao nhiêu ngoặc đơn ngoặc kép gì trong chuỗi cũng được (miễn là đừng có dùng ba dấu ngoặc đơn trong đó). Đây là phiên bản ngon lành của chuỗi lúc nãy:
silly_string = '''He said, "Aren't can't shouldn't wouldn't."''' À khoan, còn cái này nữa. Nếu thực sự chỉ
muốn dùng ngoặc đơn hoặc ngoặc kép để bọc
chuỗi trong Python thay vì ba dấu ngoặc kia, em
có thể dùng dấu gạch ngược (\) trước mỗi dấu
ngoặc bị trùng bên trong chuỗi. Việc này gọi là
thoát ra ⟨escape⟩. Đây là cách để ta nói với Python
rằng “OK, tôi biết trong chuỗi của tôi có ngoặc bị
trùng rồi, đề nghị anh bỏ qua cho tới khi anh nhìn
thấy dấu đóng ngoặc thật sự nhá.”
Việc viết thêm các ký tự thoát vào có thể khiến cho chuỗi trở nên khó đọc hơn, nên dùng chuỗi nhiều dòng phần nào đó ổn hơn. Nhưng biết đâu về sau em lại gặp những đoạn code có dùng ký tự thoát, cho nên dù sao đi nữa, hiểu ý nghĩa của mấy cái dấu gạch ngược này vẫn hơn nhỉ.
Đây là vài ví dụ về ký tự thoát:
>>> single_quote_str = 'He said, "Aren\'t can\'t shouldn\'t wouldn\'t."' >>> double_quote_str = "He said, \"Aren't can't shouldn't wouldn't.\""
>>> print(single_quote_str)
He said, "Aren't can't shouldn't wouldn't."
>>> print(double_quote_str)
He said, "Aren't can't shouldn't wouldn't."
Đầu tiên ở ❶, ta tạo ra một chuỗi bằng ngoặc đơn, sử dụng dấu gạch ngược để thoát khỏi các ngoặc đơn khác bên trong chuỗi. Sau đó ở ❷, ta tạo ra một chuỗi khác bằng dấu ngoặc kép và sử dụng dấu gạch ngược để thoát khỏi các ngoặc kép khác bên trong chuỗi. Dòng cuối cùng ta in các biến vừa được tạo. Em có thể thấy là mấy dấu gạch ngược này hoàn toàn vô hình lúc in nhé.
Chuỗi, mảng, tuple và map 27
GHÉP GIÁ TRỊ VÀO TRONG CHUỖI
Nếu cần viết ra câu gì đó có dính dáng đến dữ liệu của một biến, em có thể ghép chúng vào nội dung của chuỗi bằng cách dùng %s, một kiểu đánh dấu chỗ cho các giá trị về sau sẽ được thay vào. (Ghép giá trị ⟨embedding value⟩, hay còn được gọi là thay thế nội dung trong chuỗi ⟨string substitution⟩, là cách lập trình viên mô tả việc “đưa một giá trị nào đó vào bên trong chuỗi.”) Ví dụ, sau khi Python tính toán hoặc lưu lại điểm số trong một game, để nhét số điểm đó vào trong một câu kiểu “Tôi đã ghi được ___ điểm,” em có thể dùng %s ngay chỗ gạch gạch kia, rồi nói Python giá trị đó là gì, như sau:
>>> myscore = 1000
>>> message = 'I scored %s points'
>>> print(message % myscore)
I scored 1000 points
Ta vừa tạo ra biến myscore với giá trị 1000 và biến message là một chuỗi với câu “I scored %s points,” trong đó %s là ký tự đặt chỗ cho số điểm ghi được. Dòng tiếp theo ta gọi print(message) với ký hiệu % để nói Python hãy thay %s bằng giá trị của myscore vào. Kết quả là câu I scored 1000 points được in ra. Ở đây ta không nhất thiết phải sử dụng biến, viết như thế này cũng được print(message % 1000).
Ta cũng có thể đưa các giá trị khác nhau vào chỗ %s bằng cách dùng các biến khác nhau như sau:
>>> joke_text = '%s: a device for finding furniture in the dark' >>> bodypart1 = 'Knee'
>>> bodypart2 = 'Shin'
>>> print(joke_text % bodypart1)
Knee: a device for finding furniture in the dark4
>>> print(joke_text % bodypart2)
Shin: a device for finding furniture in the dark5
4 Câu đùa: “Đầu gối: là dụng cụ tìm đồ trong bóng đêm” (va vào đâu là biết ngay ở đấy có đồ) 5 Câu đùa: “Cẳng chân: là dụng cụ tìm đồ trong bóng đêm”
28 Chương 3
Ở đây ta có tổng cộng ba biến. Biến đầu tiên joke_text là chuỗi có ký tự đặt chỗ %s. Các biến còn lại là bodypart1 và bodypart2. Khi ta in ra biến joke_text, ký hiệu % được sử dụng để thay giá trị của bodypart1 và
bodypart2 vào để sinh ra hai câu khác nhau.
Em cũng có thể dùng nhiều ký tự đặt chỗ cùng lúc, như thế này:
>>> nums = 'What did the number %s say to the number %s? Nice belt!!'
>>> print(nums % (0, 8))
What did the number 0 say to the number 8? Nice belt!!
Khi có nhiều ký tự đặt chỗ trong câu, nhớ là phải dùng ngoặc tròn để bọc những giá trị thay thế vào như bên trên nhé. Các giá trị cần được sắp xếp theo đúng thứ tự chúng được dùng trong chuỗi.
DÙNG PHÉP NHÂN TRONG CHUỖI
10 nhân 5 là bao nhiêu? 50, quá dễ. 10 nhân với a thì sao? Python trả lời:
>>> print(10 * 'a')
aaaaaaaaaa
Lập trình viên giả dụ có thể dùng cách này để thêm các khoảng trắng và xếp các chuỗi cho thẳng hàng. Một bức thư trong shell trông sẽ như thế nào nhỉ? (chọn File ► New Window và nhập vào đoạn code này nhé):
spaces = ' ' * 25
print('%s 12 Butts Wynd' % spaces)
print('%s Twinklebottom Heath' % spaces)
print('%s West Snoring' % spaces)
print()
print()
print('Dear Sir')
print()
print('I wish to report that tiles are missing from the')
print('outside toilet roof.')
print('I think it was bad wind the other night that blew them away.') print()
print('Regards')
print('Malcolm Dithering')
Chuỗi, mảng, tuple và map 29
Sau khi nhập xong trong cửa sổ shell, chọn File ► Save As. Đặt tên file là myletter.py. Giờ em có thể chạy nó bằng cách chọn Run ► Run Module.
CHÚ Ý
Từ giờ, nếu đằng trước một đống code em thấy Save As: somefilename.py thì có nghĩa là em sẽ phải chọn File ► New Window, gõ đống code đó vào, rồi lưu lại file như ta vừa làm, nhé.
Ở dòng đầu tiên của ví dụ này, ta tạo ra biến spaces bằng cách nhân một dấu cách với số 25. Biến này được dùng ở ba dòng tiếp theo để dóng câu chữ cho thẳng hàng sang phía bên phải. Kết quả của mấy hàm print trên trông sẽ như thế này:
Ngoài việc dùng để dóng hàng, ta cũng có thể dùng phép nhân chuỗi để in kín màn hình cho vui:
>>> print(1000 * 'snirt')
30 Chương 3
MẢNG CÒN KHỦNG HƠN CHUỖI
“Chân nhện, ngón ếch, mắt kỳ nhông, cánh dơi, bơ ốc sên, vẩy
rắn”, đây hẳn là một danh sách mua sắm hết sức không bình thường (tất nhiên, trừ khi em là phù thủy), ở đây ta sẽ dùng nó làm ví dụ để
thấy sự khác biệt giữa chuỗi và mảng nhé.
Ta có thể dùng chuỗi để lưu lại danh sách này vào biến
wizard_list như sau:
>>> wizard_list = 'spider legs, toe of frog, eye of newt, bat wing, slug butter, snake dandruff'
>>> print(wizard_list)
spider legs, toe of frog, eye of newt, bat wing, slug butter, snake dandruff Nhưng mặt khác ta cũng có thể tạo ra một mảng ⟨list⟩, một kiểu khá kỳ diệu trong Python, kiểu mà ta có thể can thiệp vào từng phần tử của nó rất dễ dàng. Ta sẽ viết mảng như sau:
>>> wizard_list = ['spider legs', 'toe of frog', 'eye of newt', 'bat wing', 'slug butter', 'snake dandruff']
>>> print(wizard_list)
['spider legs', 'toe of frog', 'eye of newt', 'bat wing', 'slug butter', 'snake dandruff']
Mảng thường phải gõ nhiều hơn chuỗi một chút, nhưng bù lại ta lại có nhiều quyền điều khiển hơn chuỗi. Ví dụ, ta có thể in ra món thứ ba trong wizard_list (là mắt kỳ nhông) bằng cách nhập vào vị trí của nó ở trong mảng (còn gọi là vị trí chỉ mục ⟨index position⟩) bên trong một cặp ngoặc vuông ([]) như sau:
>>> print(wizard_list[2])
eye of newt
Ủa, em tưởng là món thứ ba cơ mà? Đúng, nhưng thứ tự trong mảng lại bắt đầu từ vị trí 0 cơ, cho nên món đầu tiên sẽ ở vị trí 0, món thứ hai ở vị trí 1 và món thứ ba ở vị trí 2. Mình là người tuy nghe không hợp lý lắm nhưng máy tính thì hiểu thế đấy.
Chuỗi, mảng, tuple và map 31
So với chuỗi, khi dùng mảng ta có thể sửa lại danh sách này dễ dàng hơn nhiều. Giả sử thay vì mắt kỳ nhông ta cần lưỡi ốc cơ. Ta có thể làm như sau với mảng:
>>> wizard_list[2] = 'snail tongue'
>>> print(wizard_list)
['spider legs', 'toe of frog', 'snail tongue', 'bat wing', 'slug butter', 'snake dandruff']
Như vậy, ta vừa mới nhét món mới lưỡi ốc vào trong mảng ở vị trí thứ 2, lúc trước là mắt kỳ nhông.
Một thao tác khác là khi ta chỉ cần một phần con của
mảng chứ không cần hết toàn bộ mảng. Ta sẽ dùng dấu hai
chấm (:) bên trong ngoặc vuông. Ví dụ, gõ đoạn code sau để có
được một phần nhỏ của danh sách trên, từ món thứ ba đến thứ
năm (các nguyên liệu chuẩn chỉnh cho một chiếc bánh mỳ kẹp
cái-gì-đó-không-phải-thịt):
>>> print(wizard_list[2:5])
['snail tongue', 'bat wing', 'slug butter']
Viết [2:5] đồng nghĩa với, “chỉ đưa ra những món nào từ vị trí số 2 đến vị trí số 5 (nhưng không bao gồm cái số 5 nhé)” – hoặc nói cách khác là mấy món số 3, 4, 5.
Mảng có thể chứa tất cả các thể loại dữ liệu, từ số:
>>> some_numbers = [1, 2, 5, 10, 20]
Đến chữ:
>>> some_strings = ['Which', 'Witch', 'Is', 'Which']
Hoặc cả số lẫn chữ:
>>> numbers_and_strings = ['Why', 'was', 6, 'afraid', 'of', 7, 'because', 7, 8, 9]
>>> print(numbers_and_strings)
['Why', 'was', 6, 'afraid', 'of', 7, 'because', 7, 8, 9]
Hoặc thậm chí chứa cả một mảng khác:
32 Chương 3
>>> numbers = [1, 2, 3, 4]
>>> strings = ['I', 'kicked', 'my', 'toe', 'and', 'it', 'is', 'sore'] >>> mylist = [numbers, strings]
>>> print(mylist)
[[1, 2, 3, 4], ['I', 'kicked', 'my', 'toe', 'and', 'it', 'is', 'sore']] Ví dụ mảng-trong-mảng này có ba biến: numbers có bốn số, strings có tám chữ và mylist dùng cả numbers lẫn strings. Mảng thứ ba (mylist) chỉ có hai phần tử thôi vì nó chỉ chứa hai biến kia, chứ không chứa các phần tử của hai biến kia.
THÊM PHẦN TỬ VÀO MẢNG
Để thêm phần tử vào mảng, ta sẽ sử dụng hàm append. Hàm ⟨function⟩ là một mớ Python code thực hiện một việc cụ thể nào đó. Trong trường hợp này, append sẽ nhét thêm một phần tử vào cuối mảng.
Ví dụ, để thêm hơi thở của gấu (có thứ đó luôn hả trời ^^) vào danh sách mua sắm của bà phù thủy kia, ta làm như thế này:
>>> wizard_list.append('bear burp')
>>> print(wizard_list)
['spider legs', 'toe of frog', 'snail tongue', 'bat wing', 'slug butter', 'snake dandruff', 'bear burp']
Tương tự, em có thể kéo dài danh sách những thứ kì quặc này ra, như này:
>>> wizard_list.append('mandrake')
>>> wizard_list.append('hemlock')
>>> wizard_list.append('swamp gas')
Danh sách mua sắm giờ dài như này:
>>> print(wizard_list)
['spider legs', 'toe of frog', 'snail tongue', 'bat wing', 'slug butter', 'snake dandruff', 'bear burp', 'mandrake', 'hemlock', 'swamp gas']
Bà phù thủy này chắc chắn đang âm mưu gì đó!
Chuỗi, mảng, tuple và map 33
XÓA PHẦN TỬ TRONG MẢNG
Để bỏ một phần tử ra khỏi mảng, dùng lệnh del (viết tắt của từ xóa ⟨delete⟩). Ví dụ, để bỏ phần tử số sáu ra khỏi danh sách đồ phù thủy kia, là vẩy rắn, thì làm thế này:
>>> del wizard_list[5]
>>> print(wizard_list)
['spider legs', 'toe of frog', 'snail tongue', 'bat wing', 'slug butter', 'bear burp', 'mandrake', 'hemlock', 'swamp gas']
CHÚ Ý
Đừng quên là các vị trí đều bắt đầu từ 0, nên wizard_list[5] thực ra là phần tử thứ sáu trong danh sách.
Để bỏ đi những thứ ta vừa mới thêm vào lúc nãy:
>>> del wizard_list[8]
>>> del wizard_list[7]
>>> del wizard_list[6]
>>> print(wizard_list)
['spider legs', 'toe of frog', 'snail tongue', 'bat wing', 'slug butter', 'bear burp']
CÁC PHÉP TOÁN VỚI MẢNG
Ta có thể ghép các mảng vào với nhau bằng dấu cộng (+), giống như cộng số ấy. Giả sử ta có hai mảng: list1 chứa từ số 1 đến số 4 và list2 chứa vài từ. Ta có thể ghép chúng lại với nhau bằng dấu + và in ra bằng print như sau:
>>> list1 = [1, 2, 3, 4]
>>> list2 = ['I', 'tripped', 'over', 'and', 'hit', 'the', 'floor']
>>> print(list1 + list2)
[1, 2, 3, 4, 'I', 'tripped', 'over', 'and', 'hit', 'the', 'floor'] Ta cũng có thể ghép hai mảng vào rồi gán kết quả cho một biến khác.
34 Chương 3
>>> list1 = [1, 2, 3, 4]
>>> list2 = ['I', 'ate', 'chocolate', 'and', 'I', 'want', 'more'] >>> list3 = list1 + list2
>>> print(list3)
[1, 2, 3, 4, 'I', 'ate', 'chocolate', 'and', 'I', 'want', 'more'] Ta cũng có thể nhân mảng với một số. Ví dụ nhân list1 với 5 ta viết là list1 * 5:
>>> list1 = [1, 2]
>>> print(list1 * 5)
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
Thực ra là ta vừa bảo Python lặp lại list1 năm lần, kết quả là ta có 1, 2, 1, 2, 1, 2, 1, 2, 1, 2.
Nhưng mặt khác, phép chia (/) và phép trừ (-) lại không như thế, lỗi luôn, ví dụ:
>>> list1 / 20
Traceback (most recent call last):
File "", line 1, in
list1 / 20
TypeError: unsupported operand type(s) for /: 'list' and 'int'
>>> list1 - 20
Traceback (most recent call last):
File "", line 1, in
list1 - 20
TypeError: unsupported operand type(s) for -: 'list' and 'int' Nhưng, tại sao lại thế? Thế này, ghép các mảng với nhau bằng dấu + hay lặp lại nó bằng dấu * nghe cũng khá hợp lý đúng không. Nghe hợp lý cả ở ngoài đời ấy chứ. Ví dụ, nếu ai đó đưa em hai tờ danh sách để đi mua hàng và bảo , “Cộng hai danh sách này vào,” em có thể hiểu và viết tuốt tuồn tuột đúng thứ tự cả hai danh sách này ra một danh sách khác, đúng không nào. Tương tự như thế, nếu bảo, “Danh sách này nhân 3 lên nhé,” em có thể hình dung ra ngay là viết lại danh sách này ba lần ra một danh sách khác.
Nhưng em sẽ chia mảng ra như thế nào? Giả sử em sẽ làm thế nào để chia một mảng có 6 số (1 đến 6) thành hai phần? Dưới đây mới chỉ là ba cách tạm thôi nhé:
Chuỗi, mảng, tuple và map 35
[1, 2, 3] [4, 5, 6]
[1] [2, 3, 4, 5, 6]
[1, 2, 3, 4] [5, 6]
Ta sẽ chia nó ra ở giữa, hay là sau phần tử đầu tiên, hay là chọn
bừa một chỗ nào đó rồi chia nó ra? Câu trả lời không hề đơn giản đúng không, và nếu em hỏi Python, nó cũng sẽ không biết đâu. Thế nên nó mới báo lỗi.
Câu trả lời cũng tương tự như thế nếu em cộng một cái gì đấy
không phải là mảng vào một mảng. Không làm thế được. Ví dụ nếu em thử thêm số 50 vào list1:
>>> list1 + 50
Traceback (most recent call last):
File "", line 1, in
list1 + 50
TypeError: can only concatenate list (not "int") to list
Lỗi ở đây là như nào vậy? Được rồi, ý em là sao khi muốn cộng 50 vào một mảng? Cộng 50 vào mỗi phần tử à? Nếu phần tử không phải số thì sao? Hay là muốn cộng số 50 vào đầu mảng hay cuối mảng hay gì?
Trong lập trình máy tính, các câu lệnh cần phải chạy y xì như nhau mỗi khi được gọi. Máy tính ngố lắm chỉ có thể hiểu đen với trắng thôi. Bảo nó tự đưa ra quyết định là nó xoè ra lỗi ngay.
TUPLE
Một tuple giống một mảng nhưng lại dùng dấu ngoặc tròn, ví dụ:
>>> fibs = (0, 1, 1, 2, 3)
>>> print(fibs[3])
2
Ta vừa mới tạo ra một biến fibs chứa các số 0, 1, 1, 2 và 3. Và cũng như mảng, ta in phần tử ở vị trí thứ 3 của tuple ra bằng print(fibs[3]).
36 Chương 3
Cái khác biệt lớn nhất giữa tuple và mảng, là một khi đã tạo ra tuple rồi, em không thể sửa nó được nữa. Ví dụ, thử thay giá trị đầu tiên của tuple fibs thành 4 (giống như cách mình thay giá trị của mảng wizard_list), ta sẽ gặp lỗi ngay:
>>> fibs[0] = 4
Traceback (most recent call last):
File "", line 1, in
fibs[0] = 4
TypeError: 'tuple' object does not support item assignment
Thế sao ta lại phải dùng tuple làm gì? Rất đơn giản, là bởi vì nhiều khi em biết có những thứ không bao giờ thay đổi cả. Nếu em tạo ra một tuple có hai phần tử thì nó chắc chắn luôn luôn chỉ có hai phần tử.
PYTHON MAPS KHÔNG CHỈ ĐƯỜNG CHO EM ĐÂU 6
Trong Python, một map (hay còn gọi là dict, viết tắt của từ điển
⟨dictionary⟩) là một tập hợp của nhiều thứ, tương tự mảng và tuple.
Điểm khác biệt ở đây là mỗi phần tử trong map đều có một khóa ⟨key⟩ và tương ứng với nó là một giá trị ⟨value⟩.
Ví dụ, giả sử em có một danh sách bạn bè và môn thể thao yêu
thích của từng người. Ta có thể cho hết danh sách này vào một mảng, tên người đứng trước môn thể thao theo sau, như thế này:
>>> favorite_sports = ['Ralph Williams, Football',
'Michael Tippett, Basketball',
'Edward Elgar, Baseball',
'Rebecca Clarke, Netball',
'Ethel Smyth, Badminton',
'Frank Bridge, Rugby']
Hỏi, bạn Rebecca Clarke thích môn gì? Em có thể đọc lướt qua mảng này và tìm ra câu trả lời là netball (bóng lưới). Nhưng nhỡ mảng này mà dài đến 100 người (hoặc nhiều hơn nữa) thì sao?
6 Ý nói Python Maps so với Google Maps ^^
Chuỗi, mảng, tuple và map 37
Nếu ta lưu lại cũng từng ấy thông tin vào trong một map, với tên người là khóa và môn thể thao là giá trị, code Python sẽ trông như thế này:
>>> favorite_sports = {'Ralph Williams' : 'Football',
'Michael Tippett' : 'Basketball',
'Edward Elgar' : 'Baseball',
'Rebecca Clarke' : 'Netball',
'Ethel Smyth' : 'Badminton',
'Frank Bridge' : 'Rugby'}
Ta dùng dấu hai chấm để tách khóa với giá trị, và mỗi khóa và giá trị đều phải được bọc bởi dấu ngoặc đơn. Chú ý nữa là toàn bộ các phần tử trong map phải được bọc lại bằng một cặp ngoặc nhọn ({}), không phải ngoặc tròn, cũng không phải ngoặc vuông nhé.
Kết quả ta có là một mảng đối chiếu (mỗi khóa tương ứng với một giá trị) như Bảng 3-1.
Bảng 3-1: Các khóa trỏ đến các giá trị tương ứng trong Môn thể thao yêu thích
Khóa
Giá trị
Ralph Williams
Football (Bóng đá)
Michael Tippett
Basketball (Bóng rổ)
Edward Elgar
Baseball (Bóng chày)
Rebecca Clarke
Netball (Bóng lưới)
Ethel Smyth
Badminton (Cầu lông)
Frank Bridge
Rugby (Bóng bầu dục)
Giờ để xem môn thể thao yêu thích của Rebecca Clarke là gì, ta truy cập vào map favorite_sports và dùng tên của cô làm khóa, như thế này:
>>> print(favorite_sports['Rebecca Clarke'])
Netball
Vậy câu trả lời là netball (bóng lưới).
38 Chương 3
Để xóa một giá trị trong map, ta cũng dùng khóa luôn. Ví dụ để xóa Ethel Smyth:
>>> del favorite_sports['Ethel Smyth']
>>> print(favorite_sports)
{'Rebecca Clarke': 'Netball', 'Michael Tippett': 'Basketball', 'Ralph Williams': 'Football', 'Edward Elgar': 'Baseball', 'Frank Bridge': 'Rugby'}
Để thay đổi giá trị trong map, ta cũng dùng khóa nốt:
>>> favorite_sports['Ralph Williams'] = 'Ice Hockey'
>>> print(favorite_sports)
{'Rebecca Clarke': 'Netball', 'Michael Tippett': 'Basketball', 'Ralph Williams': 'Ice Hockey', 'Edward Elgar': 'Baseball', 'Frank Bridge': 'Rugby'}
Ta vừa mới đổi môn thể thao yêu thích của Ralph Williams từ Football thành Ice Hockey đó.
Em cũng thấy đấy, dùng map cũng đại khái giống dùng mảng và tuple thôi, trừ việc em không thể ghép hai map vào với nhau bằng dấu cộng (+) được. Thử đi, em sẽ gặp lỗi này:
>>> favorite_sports = {'Rebecca Clarke': 'Netball',
'Michael Tippett': 'Basketball',
'Ralph Williams': 'Ice Hockey',
'Edward Elgar': 'Baseball',
'Frank Bridge': 'Rugby'}
>>> favorite_colors = {'Malcolm Warner': 'Pink polka dots', 'James Baxter': 'Orange stripes',
'Sue Lee': 'Purple paisley'}
>>> favorite_sports + favorite_colors
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'dict' and 'dict' Python không hiểu nổi ghép các map vào như thế nào đâu, nên nó bắn ra lỗi thôi.
Chuỗi, mảng, tuple và map 39
TÓM TẮT
Trong chương này, em đã hiểu Python dùng chuỗi để lưu dữ liệu dạng chữ như thế nào, và nó dùng mảng và tuple để xử lý nhiều phần tử cùng nhau như thế nào. Em cũng đã thấy các phần tử của mảng có thể thay đổi được, cũng có thể ghép hai mảng vào với nhau, nhưng các phần tử của tuple thì không thế được. Em cũng học được là map lưu các giá trị với các khóa tương ứng như thế nào.
BÀI TẬP LẬP TRÌNH
Dưới đây là một vài bài tập để em có thể tự làm. Câu trả lời có thể tìm thấy trên http://python-for-kids.com/.
#1: SỞ THÍCH
Hãy lập ra một danh sách các trò chơi yêu thích của em, đưa vào một biến đặt tên là games. Tiếp đó lập ra một danh sách các món ăn yêu thích, đặt tên biến là foods. Ghép hai danh sách này lại với nhau và tạo ra biến mới tên là favorites. Cuối cùng in biến favorites ra.
#2: ĐẾM NGƯỜI
Có 25 ninja trốn trong mỗi nóc của 3 tòa nhà và 40 samurai trốn trong mỗi hầm của 2 đường hầm, hỏi tất cả có bao nhiêu người chuẩn bị đánh nhau? (Bài này em có thể giải chỉ bằng một biểu thức trong Python shell.)
#3: CHÀO!
Tạo ra 2 biến: một lưu tên và một lưu họ của em. Tạo ra một chuỗi và dùng ký tự đặt chỗ để in ra câu chào sử dụng hai biến kia, ví dụ như Chao xìn ^^, tôi là Brando Ickett!
40 Chương 3
Rùa ⟨turtle⟩ trong Python cũng đại khái như rùa thật. Ta đều biết rùa là một loài bò sát di chuyển siêuuuu chậm và luôn mang cái mai trên mình. Trong thế giới Python, rùa là một mũi tên đen đen, nhỏ nhỏ, di chuyển chầm chậm quanh màn hình máy tính. Chưa kể, vì con rùa trong Python khi đi để lại các vết trên màn hình, nên kể ra thì nó giống ốc sên hơn là giống rùa.
Rùa là cách rất thú vị để ta có thể tiếp cận với những kiến thức căn bản của đồ hoạ máy tính, nên chương này ta sẽ dùng rùa trong Python để vẽ một vài hình và đoạn thẳng đơn giản.
SỬ DỤNG MODULE TURTLE TRONG PYTHON
Module trong Python là một cách để đưa những đoạn code hữu dụng cho những chương trình khác sử dụng (trong module có chứa rất nhiều thứ, ở đây ta chỉ đề cập đến hàm thôi). Module sẽ được nói kỹ hơn trong Chương 7. Python có một module rất đặc biệt tên là turtle mà ta sẽ dùng để học và hiểu cách máy tính vẽ trên màn hình như thế nào.
Vẽ vời với rùa 41
Module turtle là một cách để lập trình đồ
họa vector, nói đơn giản là để vẽ ra các điểm, đường
thẳng và đường cong.
Ta sẽ xem xem dùng turtle như thế nào
nhé. Đầu tiên, bật Python shell lên như hướng dẫn
trong Chương 1. Tiếp, yêu cầu Python sử dụng
turtle bằng cách mang module turtle vào, như thế
này:
>>> import turtle
Mang một module vào nghĩa là em nói Python em muốn dùng module đó.
CHÚ Ý
Nếu đang dùng Ubuntu bản cũ hơn 14.04 và gặp lỗi ở đây, em có thể sẽ phải cài tkinter. Mở Ubuntu Software Center ra và gõ python-tk vào ô tìm kiếm. Em sẽ thấy có kết quả Tkinter – Writing Tk Applications with Python trả về. Nhấn Install để cài.
TẠO BẢNG VẼ
Sau khi mang module turtle vào, việc tiếp theo ta phải làm là tạo ra bảng vẽ ⟨canvas⟩ – một vùng trắng tinh để vẽ, giống như bảng vẽ của họa sĩ ấy. Bảng vẽ sẽ tự động được mở ra khi ta sẽ gọi hàm Pen từ module turtle (hàm là gì từ từ ta sẽ học nhé). Nhập dòng sau vào Python shell:
>>> t = turtle.Pen()
42 Chương 4
Em sẽ thấy một cửa sổ trắng (bảng vẽ của mình đấy), với một cái mũi tên nằm chính giữa, như thế này:
Mũi tên ở giữa này chính là con rùa của chúng ta, đúng là trông không giống rùa tí nào nhỉ.
DI CHUYỂN RÙA
Em sẽ điều khiển rùa bằng
các hàm có sẵn trong biến t vừa tạo
ra bên trên, tương tự như cách ta
dùng hàm Pen trong module turtle
vậy. Ví dụ, hàm forward sẽ di chuyển
rùa đi tới phía trước. Để rùa di
chuyển tiến tới phía trước 50 điểm ảnh, nhập lệnh sau:
>>> t.forward(50)
Vẽ vời với rùa 43
Em sẽ thấy nó di chuyển như thế này:
Như vậy là con rùa đã di chuyển được 50 điểm ảnh. Mỗi điểm ảnh ⟨pixel⟩ là một điểm ở trên màn hình – là đơn vị nhỏ nhất trên màn hình. Tất cả mọi thứ em nhìn thấy trên màn hình máy tính đều được sinh ra từ các điểm ảnh, là các hình vuông bé xíu xíu. Nếu có phóng to thật to bảng vẽ và đoạn thẳng được rùa vừa mới vẽ ra, em sẽ thấy cái mũi tên đại diện cho đường đi của rùa thực chất chỉ là một loạt các điểm ảnh mà thôi. Đây chính là điểm căn bản trong đồ họa máy tính đấy.
44 Chương 4
Giờ ta sẽ bảo rùa xoay sang trái 90 độ bằng lệnh sau:
>>> t.left(90)
Nếu vẫn chưa được học về độ góc, em có thể hình dung như thế này. Tưởng tượng em đang đứng ở chính giữa một hình tròn.
● Góc em đang hướng thẳng mặt đến sẽ là 0 độ.
● Nếu giơ tay trái sang ngang, đó sẽ là 90 độ bên trái.
● Nếu giơ tay phải sang ngang, đó sẽ là 90 độ bên phải.
Em có thể thấy các góc 90 độ trái và phải trên hình sau:
Nếu cứ liên tục xoay quanh tâm hình tròn như thế sang phía bên phải, 180 độ sẽ là ngay sau lưng em, 270 độ chính là chỗ bên tay trái, còn 360 độ chính là nơi em bắt đầu; các giá trị của độ đi từ 0 đến 360. Các góc cách nhau 45 độ trong một hình tròn nếu ta xoay từ bên phải sẽ trông như thế này:
Vẽ vời với rùa 45
Khi bảo rùa xoay sang trái, nó sẽ xoay mặt sang hướng mới (cũng như khi em xoay người để hướng mặt về phía 90 độ bên trái).
Câu lệnh Python t.left(90) sẽ xoay mũi tên lên trên (vì lúc bắt đầu nó quay mặt sang phía bên phải mà):
CHÚ Ý
Lệnh t.left(90) tương đương với t.right(270). Cũng như t.right(90) tương đương với t.left(270). Cứ tưởng tượng ra hình tròn bên trên rồi xoay theo các số độ rồi em sẽ quen thôi.
Giờ ta sẽ thử vẽ một hình vuông nhé. Gõ mấy dòng code sau nối tiếp vào đoạn code trước:
>>> t.forward(50)
>>> t.left(90)
46 Chương 4
>>> t.forward(50)
>>> t.left(90)
>>> t.forward(50)
>>> t.left(90)
Rùa lúc này đã vẽ được một hình vuông và quay trở về vị trí ban đầu:
Để xóa trắng hết bảng vẽ ta dùng lệnh reset. Hàm này sẽ tẩy toàn bộ bảng và đưa rùa về vị trí ban đầu.
>>> t.reset()
Em cũng có thể dùng hàm clear, nhưng hàm này chỉ xóa mỗi màn hình thôi, còn rùa vẫn ở nguyên vị trí hiện tại.
>>> t.clear()
Vẽ vời với rùa 47
Ta cũng có thể xoay rùa sang phải bằng hàm right hoặc cho nó đi lùi bằng hàm backward. Hàm up sẽ “nhấc bút lên khỏi giấy” (tức là rùa sẽ dừng không vẽ khi di chuyển nữa), và hàm down sẽ cho phép ta bắt đầu vẽ lại. Các hàm này được dùng tương tự như bên trên.
Ta sẽ vẽ thử cái gì khác dùng mấy hàm này xem sao nhé. Lần này ta sẽ điều khiển rùa để vẽ hai đoạn thẳng. Nhập đoạn code sau:
>>> t.reset()
>>> t.backward(100)
>>> t.up()
>>> t.right(90)
>>> t.forward(20)
>>> t.left(90)
>>> t.down()
>>> t.forward(100)
Việc đầu tiên ta cần làm là làm sạch
bảng và đưa rùa về vị trí ban đầu bằng lệnh
t.reset(). Tiếp, lệnh t.backward(100) lùi rùa
ngược về 100 điểm ảnh, rồi lệnh t.up() để nhấc
bút dừng vẽ.
Tiếp, lệnh t.right(90) xoay rùa 90 độ
sang bên phải, hướng về phía dưới của màn
hình rồi đi tới 20 điểm ảnh với t.forward(20).
Do hàm up được sử dụng trước đó ở dòng thứ ba
nên hiện tại ta không vẽ gì ra màn hình cả.
Xoay rùa sang trái 90 độ để nó hướng sang bên phải bằng t.left(90), sau đó đặt bút xuống bắt đầu vẽ lại với hàm down. Cuối cùng ta đã vẽ một đoạn thẳng, song song với đoạn thẳng
48 Chương 4
được vẽ lúc nãy, bằng lệnh t.forward(100). Hai đoạn thẳng song song trông sẽ như thế này:
TÓM TẮT
Trong chương này, em đã thấy sơ qua cách dùng module turtle. Ta đã cùng nhau vẽ vài đoạn thẳng đơn giản dùng các hàm xoay sang trái left, xoay sang phải right, đi tới forward và đi lùi backward. Em cũng đã thấy hàm up là để dừng vẽ và hàm down là để quay lại vẽ tiếp. Và ta cũng đã học thêm một chút về xoay rùa theo góc độ nữa.
BÀI TẬP LẬP TRÌNH
Hãy dùng rùa vẽ thử vài hình đơn giản nhé. Câu trả lời có thể tìm thấy trên http://python-for-kids.com/.
Vẽ vời với rùa 49
#1: HÌNH CHỮ NHẬT
Tạo bảng vẽ mới dùng hàm Pen trong module turtle rồi vẽ lên đó một hình chữ nhật.
#2: HÌNH TAM GIÁC
Tạo một bảng vẽ khác, lần này vẽ hình tam giác. Xem lại mô hình hình tròn với các số độ trên đó (phần “Di chuyển rùa” trang 43) để nhớ lại rùa có thể xoay theo góc như thế nào.
#3: HỘP MÀ KHÔNG CÓ GÓC
Viết một chương trình để vẽ ra bốn đoạn thẳng như hình dưới đây (kích thước bao nhiêu không quan trọng, đúng hình là được):
50 Chương 4
Trong lập trình, ta thường phải đối diện với rất nhiều câu hỏi có hay không, rồi tùy vào câu trả lời mà quyết định sẽ làm hay không làm gì đó. Ví dụ ta có thể hỏi “Anh có hơn 20 tuổi không thế?” và nếu câu trả lời là có, thì ta nói “Già quá!”
Những câu hỏi kiểu này được gọi là điều kiện ⟨condition⟩, ta kết hợp các điều kiện này và các câu trả lời lại với nhau thành một lệnh if ⟨if statement⟩ . Các điều kiện có thể rất phức tạp chứ không chỉ là một câu hỏi đơn giản, và lệnh if cũng có thể được kết hợp với nhiều câu hỏi khác nhau để đưa ra các phản ứng khác nhau tùy vào mỗi câu trả lời.
Chương này ta sẽ học cách viết ra chương trình máy tính với các lệnh if như thế. Đặt câu hỏi với if và else 51
LỆNH IF
Một lệnh if trong Python được viết như thế này:
>>> age = 13
>>> if age > 20:
print('You are too old!')
Lệnh if được viết bằng từ
khóa if, theo sau đó là điều kiện và
dấu hai chấm (:), như trong if age
> 20:. Những dòng nằm sau dấu
hai chấm phải được đặt trong một
khối lệnh, và nếu câu trả lời cho câu
hỏi trên là có (hoặc là True, nói theo
đúng kiểu lập trình Python), các
lệnh trong khối lệnh sẽ được chạy.
Giờ ta sẽ nghiên cứu xem viết các
khối lệnh và điều kiện như thế nào nhé.
KHỐI LỆNH LÀ MỘT KHỐI CÁC LỆNH ^^
Khối lệnh ⟨block⟩ là một khối các câu lệnh lập trình. Ví dụ nếu điều kiện if age > 20: thỏa mãn, em hẳn là sẽ muốn làm gì đó nhiều hơn là chỉ in ra mỗi câu You are too old! (Già quá!) Em có thể sẽ muốn nói thêm cái gì đó ngầu hơn tí:
>>> age = 25
>>> if age > 20:
print('You are too old!')
print('Why are you here?')
print('Why aren\'t you mowing a lawn or sorting papers?') 52 Chương 5
Khối lệnh này được tạo ra bởi ba lệnh print và chỉ được chạy khi điều kiện age > 20 được thỏa mãn. Mỗi dòng trong khối lệnh đều có bốn dấu cách ở đầu dòng so với lệnh if bên trên. Cùng xem lại đoạn code bên trên nhưng các dấu cách được hiển thị lên nhé:
>>> age = 25
>>> if age > 20:
▯▯▯▯print('You are too old!')
▯▯▯▯print('Why are you here?')
▯▯▯▯print('Why aren\'t you mowing a lawn or sorting papers?')
Trong Python, các khoảng trắng ⟨whitespace⟩ như dấu tab (khi em ấn nút TAB) hoặc dấu cách (khi em ấn nút cách) cực kỳ quan trọng. Các đoạn code cùng hàng (được lùi vào cùng số khoảng trắng tính từ lề bên trái) sẽ được nhóm vào thành một khối lệnh, và nếu dòng code mới nào có nhiều khoảng trắng hơn dòng trước đó thì đó sẽ là bắt đầu của một khối lệnh mới nằm trong khối lệnh trước, như thế này:
Ta nhóm các câu lệnh này với nhau thành các khối lệnh vì chúng có liên quan đến nhau. Những câu lệnh này sẽ được chạy cùng nhau.
Mỗi khi thay đổi vị trí lùi đầu dòng này, về cơ bản là em đang tạo ra các khối lệnh mới. Trong ví dụ sau em sẽ thấy ba khối lệnh riêng biệt được tạo ra chỉ bằng cách lùi đầu dòng như thế:
Đặt câu hỏi với if và else 53
Tuy khối 2 và khối 3 lùi đầu dòng cùng vị trí, nhưng chúng lại là hai khối hoàn toàn tách biệt vì có một khối khác lùi đầu dòng ít hơn (ít khoảng trắng hơn) chen vào giữa.
Một điều quan trọng khác, chạy một khối lệnh có bốn khoảng trắng và một khối khác tiếp đó có sáu khoảng trắng sẽ sinh ra lỗi lùi đầu dòng ⟨indentation error⟩, vì Python cần ta dùng một chuẩn khoảng trắng giống nhau trên toàn bộ chương trình. Nên một khi em đã dùng bốn khoảng trắng để bắt đầu một khối lệnh thì em phải luôn luôn dùng bốn khoảng trắng. Ví dụ:
>>> if age > 20:
▯▯▯▯print('You are too old!')
▯▯▯▯▯▯print('Why are you here?')
Các khoảng trắng ở đây được hiển thị lên để em có thấy thấy sự khác biệt. Dòng thứ ba có sáu khoảng trắng trong khi nhẽ ra chỉ được phép có bốn.
Khi chạy đoạn code này, IDLE sẽ bôi đỏ phần nó thấy có vấn đề và hiển thị thêm một thông báo lỗi SyntaxError để giải thích:
>>> age = 25
>>> if age > 20:
print('You are too old!')
print('Why are you here?')
SyntaxError: unexpected indent
Python đã nhận ra hai khoảng trắng thừa ở đầu lệnh print thứ hai.
54 Chương 5
"""