🐍 Python cơ bản
Học lập trình bằng Python từ con số 0: biến, điều kiện, vòng lặp, chuỗi, list, dict, hàm, file, xử lý lỗi, lớp — và một dự án hoàn chỉnh.
?Khóa học dành cho ai?
Học sinh từ lớp 6 trở lên chưa từng lập trình (hoặc mới học kéo thả Scratch, Micro:bit) muốn bước sang lập trình bằng chữ. Python là cửa ngõ tới AI, khoa học dữ liệu và cả lập trình vi điều khiển (MicroPython).
📖 12 bài ngắn gọn
Mỗi bài một chủ đề, có mục tiêu, giải thích, lỗi hay gặp, bài tập.
▶ Code chạy thật
14 chương trình kèm dữ liệu nhập mẫu và kết quả chạy thật.
🏁 Dự án cuối khóa
Chương trình sổ điểm có menu, kiểm tra dữ liệu, lưu file.
⌚Lộ trình gợi ý — 12 buổi
1,5 giờ
1,5 giờ
1,5 giờ
2 giờ
1,5 giờ
→Học tiếp
🤖 AI cơ bản
Hồi quy, phân loại, mạng nơ-ron với numpy và scikit-learn.
🔌 Arduino & ESP32
Điều khiển LED, cảm biến, động cơ, WiFi.
💻 C++ cơ bản → nâng cao
Ngôn ngữ chính của lập trình nhúng.
🐍 Làm quen với Python
Biết Python là gì, cài đặt và chạy chương trình đầu tiên; dùng Python như một máy tính bỏ túi.
- Cài Python và trình soạn thảo (Thonny / VS Code)
- Viết, lưu và chạy file .py
- Dùng print(), chú thích và các phép tính cơ bản
1Python là gì, dùng để làm gì?
Python là ngôn ngữ lập trình do Guido van Rossum tạo ra năm 1991. Cú pháp gần với tiếng Anh, ít ký hiệu rườm rà nên rất hợp cho người mới — nhưng cũng là ngôn ngữ số 1 cho AI, khoa học dữ liệu và tự động hoá. Python là ngôn ngữ thông dịch: chạy từng dòng, không cần biên dịch trước.
2Cài đặt
| Cách | Phù hợp |
|---|---|
| Thonny (thonny.org) – cài một lần có sẵn Python | học sinh mới bắt đầu, có chế độ chạy từng bước; nạp được MicroPython cho ESP32 |
| python.org + VS Code (extension Python) | học lâu dài, làm dự án. Khi cài nhớ tick Add python.exe to PATH |
| Chạy trên web: online-python.com, Google Colab | không cài gì, dùng máy trường |
Hai cách chạy: gõ từng lệnh trong chế độ tương tác (dấu nhắc >>>) hoặc lưu thành file bai1.py rồi chạy python bai1.py.
3Chương trình đầu tiên
# Chương trình Python đầu tiên
# Dòng bắt đầu bằng dấu # là chú thích: Python bỏ qua, chỉ để người đọc hiểu.
print("Xin chào, Python!")
print("Mình đang học lập trình", "cùng thầy Tuyền") # print in nhiều giá trị, cách nhau bởi dấu cách
print() # in một dòng trống
# Python là một chiếc máy tính bỏ túi rất mạnh
print("2 + 3 =", 2 + 3)
print("7 / 2 =", 7 / 2) # chia ra số thực
print("7 // 2 =", 7 // 2) # chia lấy phần nguyên
print("7 % 2 =", 7 % 2) # chia lấy dư
print("2 ** 10 =", 2 ** 10) # lũy thừa
print("2 ** 100 =", 2 ** 100) # số nguyên Python lớn bao nhiêu cũng được!
# In nhiều dòng và ký tự đặc biệt
print("Dòng 1\nDòng 2\tcó tab")
print("=" * 30) # nhân chuỗi với số
print("Python được đặt tên theo nhóm hài Monty Python, không phải con trăn 🐍")
python 01-xin-chao.pyXin chào, Python! Mình đang học lập trình cùng thầy Tuyền 2 + 3 = 5 7 / 2 = 3.5 7 // 2 = 3 7 % 2 = 1 2 ** 10 = 1024 2 ** 100 = 1267650600228229401496703205376 Dòng 1 Dòng 2 có tab ============================== Python được đặt tên theo nhóm hài Monty Python, không phải con trăn 🐍
Giải thích
print(...)in ra màn hình; nhiều giá trị cách nhau bởi dấu phẩy sẽ được in cách một dấu cách./luôn ra số thực,//chia lấy phần nguyên,%lấy dư,**lũy thừa.- Số nguyên trong Python không giới hạn độ lớn —
2 ** 100vẫn chính xác. \nxuống dòng,\ttab;"=" * 30lặp chuỗi 30 lần.
⚠Lỗi thường gặp
- Gõ
Print(chữ P hoa) — Python phân biệt chữ hoa, chữ thường. - Quên dấu ngoặc kép quanh chữ:
print(Xin chao)→ lỗi NameError. - Thụt lề đầu dòng lung tung — Python dùng thụt lề để hiểu cấu trúc.
✎Bài tập về nhà
📦 Biến, kiểu dữ liệu và toán tử
Lưu dữ liệu vào biến, phân biệt các kiểu cơ bản và chuyển đổi giữa chúng.
- Đặt tên biến đúng quy tắc
- Hiểu int, float, str, bool và hàm type()
- Ép kiểu với int(), float(), str()
- Dùng toán tử số học, so sánh, logic
1Biến
Biến là tên dùng để giữ một giá trị: tuoi = 12. Python tự biết kiểu dựa vào giá trị, không cần khai báo trước.
Quy tắc đặt tên: chữ cái, chữ số, dấu gạch dưới; không bắt đầu bằng số; không dùng từ khoá (if, for…); phân biệt hoa thường. Quy ước: chữ thường nối bằng gạch dưới — diem_trung_binh.
2Kiểu dữ liệu, ép kiểu, toán tử
| Kiểu | Ví dụ | Ghi chú |
|---|---|---|
int | 12, -5 | số nguyên |
float | 1.52, 3e8 | số thực (có sai số nhỏ) |
str | "An", '7A' | chuỗi ký tự |
bool | True, False | đúng / sai |
# Biến, kiểu dữ liệu, ép kiểu và toán tử
# ----- Biến: tên gắn với một giá trị -----
ten = "An" # str – chuỗi
tuoi = 12 # int – số nguyên
chieu_cao = 1.52 # float – số thực
la_hoc_sinh = True # bool – đúng/sai
print(ten, tuoi, chieu_cao, la_hoc_sinh)
print(type(ten), type(tuoi), type(chieu_cao), type(la_hoc_sinh))
# Biến có thể đổi giá trị (và cả kiểu)
diem = 7
diem = diem + 1.5 # giờ là float
print("Điểm sau khi cộng:", diem)
# Gán nhiều biến cùng lúc, hoán đổi hai biến
a, b = 3, 5
a, b = b, a
print("Sau khi đổi: a =", a, ", b =", b)
# ----- Ép kiểu -----
so_chuoi = "25"
print("Chuỗi + chuỗi:", so_chuoi + so_chuoi) # nối chuỗi: 2525
print("Số + số:", int(so_chuoi) + int(so_chuoi)) # 50
print("float('3.5') =", float("3.5"), "| str(10) + '%' =", str(10) + "%")
print("int(9.99) =", int(9.99), "(cắt phần lẻ) | round(9.99) =", round(9.99))
print("bool(0) =", bool(0), "| bool('') =", bool(""), "| bool('abc') =", bool("abc"))
# ----- Toán tử -----
x = 17
print("x // 5 =", x // 5, "| x % 5 =", x % 5, "| x ** 2 =", x ** 2)
x += 3 # x = x + 3
x *= 2 # x = x * 2
print("x sau += 3 rồi *= 2:", x)
print("So sánh: 3 < 5 < 7 là", 3 < 5 < 7, "| 'a' == 'A' là", "a" == "A")
print("Logic: True and False =", True and False, "| not True =", not True)
# ----- Số thực có sai số -----
print("0.1 + 0.2 =", 0.1 + 0.2)
print("Làm tròn 2 chữ số:", round(0.1 + 0.2, 2))
python 02-bien-kieu-du-lieu.pyAn 12 1.52 True
<class 'str'> <class 'int'> <class 'float'> <class 'bool'>
Điểm sau khi cộng: 8.5
Sau khi đổi: a = 5 , b = 3
Chuỗi + chuỗi: 2525
Số + số: 50
float('3.5') = 3.5 | str(10) + '%' = 10%
int(9.99) = 9 (cắt phần lẻ) | round(9.99) = 10
bool(0) = False | bool('') = False | bool('abc') = True
x // 5 = 3 | x % 5 = 2 | x ** 2 = 289
x sau += 3 rồi *= 2: 40
So sánh: 3 < 5 < 7 là True | 'a' == 'A' là False
Logic: True and False = False | not True = False
0.1 + 0.2 = 0.30000000000000004
Làm tròn 2 chữ số: 0.3Giải thích
"25" + "25"là nối chuỗi; muốn cộng số phảiint()trước.int(9.99)cắt bỏ phần lẻ,round()mới làm tròn.a, b = b, a— cách hoán đổi hai biến đặc trưng của Python.- Số thực lưu dạng nhị phân nên
0.1 + 0.2hơi lệch; dùnground()khi in.
✎Bài tập về nhà
⌨️ Nhập dữ liệu và in kết quả đẹp
Nhận dữ liệu từ bàn phím bằng input() và trình bày kết quả gọn gàng bằng f-string.
- Dùng input() và ép kiểu kết quả
- Dùng f-string, định dạng số chữ số thập phân, căn lề
- Nhập nhiều giá trị trên một dòng
1input() và f-string
# Nhập dữ liệu với input() và in đẹp với f-string – ví dụ: tính chỉ số BMI
ten = input("Tên của bạn: ")
can_nang = float(input("Cân nặng (kg): ")) # input() luôn trả về CHUỖI -> phải ép sang số
chieu_cao = float(input("Chiều cao (m): "))
bmi = can_nang / chieu_cao ** 2
print()
print(f"Xin chào {ten}!")
print(f"Chỉ số BMI của bạn là {bmi:.1f}") # :.1f -> 1 chữ số sau dấu phẩy
print(f"{'Cân nặng':<10}|{can_nang:>8.1f} kg") # < căn trái, > căn phải, số là độ rộng
print(f"{'Chiều cao':<10}|{chieu_cao:>8.2f} m")
print(f"Tỉ lệ so với BMI 22: {bmi / 22:.0%}") # :% -> phần trăm
# Nhiều giá trị trên một dòng
a, b = map(int, input("Nhập 2 số nguyên cách nhau dấu cách: ").split())
print(f"{a} + {b} = {a + b}, {a} x {b} = {a * b}")
python 03-nhap-xuat.pyMinh 45 1.55 12 7
Tên của bạn: Minh Cân nặng (kg): 45 Chiều cao (m): 1.55 Xin chào Minh! Chỉ số BMI của bạn là 18.7 Cân nặng | 45.0 kg Chiều cao | 1.55 m Tỉ lệ so với BMI 22: 85% Nhập 2 số nguyên cách nhau dấu cách: 12 7 12 + 7 = 19, 12 x 7 = 84
Giải thích
input()luôn trả về chuỗi → muốn tính toán phảiint()/float().- f-string:
f"{bien:.1f}"1 chữ số thập phân,{x:>8}căn phải rộng 8,{x:.0%}phần trăm. map(int, input().split())tách dòng theo dấu cách rồi đổi từng phần sang số.
⚠Lỗi thường gặp
- Cộng trực tiếp hai giá trị input() → bị nối chuỗi.
- Nhập số thập phân bằng dấu phẩy (1,55) → lỗi; Python dùng dấu chấm.
✎Bài tập về nhà
🔀 Câu lệnh điều kiện
Cho chương trình ra quyết định với if / elif / else và match-case.
- Viết if – elif – else và hiểu thụt lề
- Kết hợp điều kiện bằng and, or, not
- Dùng biểu thức điều kiện một dòng và match-case
1if / elif / else
Khối lệnh thuộc if được nhận biết bằng dấu hai chấm và thụt lề 4 dấu cách. Các nhánh elif được xét lần lượt; gặp nhánh đúng đầu tiên thì bỏ qua các nhánh còn lại.
# Câu lệnh điều kiện: if / elif / else, toán tử logic, match-case
diem = float(input("Nhập điểm trung bình: "))
if diem >= 8:
xep_loai = "Giỏi"
elif diem >= 6.5:
xep_loai = "Khá"
elif diem >= 5:
xep_loai = "Trung bình"
else:
xep_loai = "Yếu"
print(f"Điểm {diem} -> xếp loại {xep_loai}")
# Kết hợp điều kiện: năm nhuận chia hết cho 4 nhưng không chia hết cho 100, hoặc chia hết cho 400
nam = int(input("Nhập một năm: "))
nhuan = (nam % 4 == 0 and nam % 100 != 0) or nam % 400 == 0
print(f"Năm {nam} {'là' if nhuan else 'không là'} năm nhuận") # biểu thức điều kiện một dòng
# Điều kiện lồng nhau
nhiet_do = 33
co_nguoi = True
if co_nguoi:
if nhiet_do > 30:
print("Có người và trời nóng -> bật quạt")
else:
print("Có người, trời mát -> tắt quạt")
else:
print("Không có người -> tắt hết")
# match-case (Python 3.10+): chọn theo giá trị
lenh = input("Lệnh điều khiển robot (tien/lui/trai/phai): ").strip().lower()
match lenh:
case "tien":
print("Robot đi thẳng")
case "lui":
print("Robot đi lùi")
case "trai" | "phai":
print(f"Robot rẽ {lenh}")
case _:
print("Không hiểu lệnh")
python 04-dieu-kien.py7.2 2024 Trai
Nhập điểm trung bình: 7.2 Điểm 7.2 -> xếp loại Khá Nhập một năm: 2024 Năm 2024 là năm nhuận Có người và trời nóng -> bật quạt Lệnh điều khiển robot (tien/lui/trai/phai): Trai Robot rẽ trai
Giải thích
- Thứ tự elif quan trọng: kiểm tra điểm từ cao xuống thấp.
- Năm nhuận là bài tập kinh điển về kết hợp
and/or. .strip().lower()chuẩn hoá chữ người dùng gõ (bỏ khoảng trắng, chữ thường) trước khi so sánh.
⚠Lỗi thường gặp
- Dùng
=thay vì==trong điều kiện. - Quên dấu
:cuối dòng if. - Thụt lề không đều (trộn tab và dấu cách).
✎Bài tập về nhà
🔁 Vòng lặp for và while
Lặp lại công việc với for/while, điều khiển vòng lặp bằng break/continue và viết trò chơi đoán số.
- Dùng for với range()
- Dùng while khi chưa biết trước số lần lặp
- Dùng break, continue, vòng lặp lồng nhau
1for, while và trò chơi đoán số
# Vòng lặp for, while, break, continue – và trò chơi đoán số
import random
# ----- for với range(bắt_đầu, dừng_trước, bước) -----
print("Đếm:", end=" ")
for i in range(1, 6):
print(i, end=" ")
print()
print("Số chẵn tới 10:", list(range(0, 11, 2)))
print("Đếm ngược:", list(range(5, 0, -1)))
# ----- Tính tổng bằng vòng lặp -----
tong = 0
for so in range(1, 101):
tong += so
print("1 + 2 + ... + 100 =", tong)
# ----- Vòng lặp lồng nhau: bảng cửu chương 2..4 -----
for i in range(1, 4):
print(" ".join(f"{b}x{i}={b * i:<2}" for b in range(2, 5)))
# ----- break và continue -----
for so in range(1, 20):
if so % 3 == 0:
continue # bỏ qua số chia hết cho 3
if so > 10:
break # dừng hẳn khi vượt 10
print(so, end=" ")
print()
# ----- while + trò chơi đoán số -----
random.seed(7) # cố định để ví dụ luôn ra cùng số bí mật
bi_mat = random.randint(1, 100)
so_lan = 0
while True:
doan = int(input("Đoán số (1-100): "))
so_lan += 1
if doan < bi_mat:
print(" -> lớn hơn nữa")
elif doan > bi_mat:
print(" -> nhỏ hơn")
else:
print(f" -> ĐÚNG RỒI! Số bí mật là {bi_mat}, bạn đoán {so_lan} lần")
break
python 05-vong-lap.py50 25 37 43 41 42
Đếm: 1 2 3 4 5 Số chẵn tới 10: [0, 2, 4, 6, 8, 10] Đếm ngược: [5, 4, 3, 2, 1] 1 + 2 + ... + 100 = 5050 2x1=2 3x1=3 4x1=4 2x2=4 3x2=6 4x2=8 2x3=6 3x3=9 4x3=12 1 2 4 5 7 8 10 Đoán số (1-100): 50 -> nhỏ hơn Đoán số (1-100): 25 -> lớn hơn nữa Đoán số (1-100): 37 -> lớn hơn nữa Đoán số (1-100): 43 -> nhỏ hơn Đoán số (1-100): 41 -> lớn hơn nữa Đoán số (1-100): 42 -> ĐÚNG RỒI! Số bí mật là 42, bạn đoán 6 lần
Giải thích
range(a, b, buoc)chạy từ a tới trước b.print(..., end=" ")in không xuống dòng.- Trò chơi dùng
random.seed(7)để số bí mật cố định — bỏ dòng này để mỗi lần chơi một số khác. - Chiến lược đoán tốt nhất là chia đôi khoảng (50 → 25 → 37…): tối đa 7 lần cho 100 số — đây là ý tưởng của tìm kiếm nhị phân.
⚠Lỗi thường gặp
- while quên cập nhật biến điều kiện → lặp vô hạn (bấm Ctrl+C để dừng).
- Nhầm range(1, 10) có cả số 10.
✎Bài tập về nhà
🔤 Xử lý chuỗi (string)
Cắt, tìm, thay thế, tách và ghép chuỗi — xử lý văn bản và dữ liệu cảm biến.
- Dùng chỉ số và cắt lát
- Dùng các phương thức upper, find, replace, split, join, strip
- Duyệt từng ký tự
1Thao tác với chuỗi
# Chuỗi (string): chỉ số, cắt lát, phương thức xử lý
s = "Lập trình Python"
print("Độ dài:", len(s))
print("Ký tự đầu:", s[0], "| ký tự cuối:", s[-1])
print("Cắt lát s[0:8]:", s[0:8], "| s[-6:]:", s[-6:], "| đảo ngược:", s[::-1])
# Phương thức thường dùng
print(s.upper(), "|", s.lower(), "|", s.title())
print("Tìm 'Python' ở vị trí:", s.find("Python"), "| đếm 'n':", s.count("n"))
print("Thay thế:", s.replace("Python", "C++"))
print("Bắt đầu bằng 'Lập'?", s.startswith("Lập"), "| chứa 'trình'?", "trình" in s)
# Tách và ghép
cau = " hôm nay trời đẹp "
tu = cau.split() # tách theo khoảng trắng, bỏ khoảng trắng thừa
print("Các từ:", tu, "-> số từ:", len(tu))
print("Ghép lại:", "-".join(tu))
print("Bỏ khoảng trắng 2 đầu:", repr(cau.strip()))
# Duyệt từng ký tự: đếm nguyên âm
nguyen_am = 0
for ch in "Embedded Programming":
if ch.lower() in "aeiou":
nguyen_am += 1
print("Số nguyên âm trong 'Embedded Programming':", nguyen_am)
# Chuỗi không thể sửa trực tiếp (immutable)
ma = "abc"
# ma[0] = "x" -> lỗi TypeError
ma = "x" + ma[1:]
print("Tạo chuỗi mới:", ma)
# Kiểm tra chuỗi đối xứng
for tu_kiem_tra in ["level", "python", "Radar"]:
t = tu_kiem_tra.lower()
print(f"'{tu_kiem_tra}' đối xứng? {t == t[::-1]}")
# Phân tích lệnh dạng "TEN:GIA_TRI" (giống dữ liệu gửi từ cảm biến)
du_lieu = "T:28.5;H:61;L:320"
for cap in du_lieu.split(";"):
ten, gia_tri = cap.split(":")
print(f" {ten} = {float(gia_tri)}")
python 06-chuoi.pyĐộ dài: 16 Ký tự đầu: L | ký tự cuối: n Cắt lát s[0:8]: Lập trìn | s[-6:]: Python | đảo ngược: nohtyP hnìrt pậL LẬP TRÌNH PYTHON | lập trình python | Lập Trình Python Tìm 'Python' ở vị trí: 10 | đếm 'n': 2 Thay thế: Lập trình C++ Bắt đầu bằng 'Lập'? True | chứa 'trình'? True Các từ: ['hôm', 'nay', 'trời', 'đẹp'] -> số từ: 4 Ghép lại: hôm-nay-trời-đẹp Bỏ khoảng trắng 2 đầu: 'hôm nay trời đẹp' Số nguyên âm trong 'Embedded Programming': 6 Tạo chuỗi mới: xbc 'level' đối xứng? True 'python' đối xứng? False 'Radar' đối xứng? True T = 28.5 H = 61.0 L = 320.0
Giải thích
s[::-1]đảo ngược chuỗi.- Chuỗi là bất biến: mọi phương thức trả về chuỗi mới.
- Phân tích chuỗi
"T:28.5;H:61"là kỹ năng dùng hằng ngày khi đọc dữ liệu từ Arduino/ESP32 qua Serial.
✎Bài tập về nhà
📋 Danh sách (list) và tuple
Lưu nhiều giá trị trong một biến, thêm/xoá/sắp xếp, dùng list comprehension.
- Tạo, truy cập, sửa list
- append, insert, remove, pop, sort, sorted
- len, sum, min, max, enumerate
- List comprehension; tuple
1Làm việc với list
# List (danh sách) và tuple
diem = [8, 6.5, 9, 7, 5.5]
print("Danh sách điểm:", diem)
print("Phần tử đầu:", diem[0], "| cuối:", diem[-1], "| 3 phần tử đầu:", diem[:3])
print("Số phần tử:", len(diem), "| tổng:", sum(diem), "| lớn nhất:", max(diem), "| nhỏ nhất:", min(diem))
print("Trung bình:", round(sum(diem) / len(diem), 2))
# Thêm / xoá / sửa
diem.append(10) # thêm vào cuối
diem.insert(0, 4) # chèn vào vị trí 0
diem[2] = 7.5 # sửa
diem.remove(5.5) # xoá theo giá trị
cuoi = diem.pop() # lấy ra phần tử cuối
print("Sau khi sửa:", diem, "| vừa lấy ra:", cuoi)
# Sắp xếp
print("sorted (tạo list mới):", sorted(diem))
diem.sort(reverse=True) # sắp xếp tại chỗ, giảm dần
print("sort giảm dần:", diem)
# Duyệt kèm chỉ số
for i, d in enumerate(diem, start=1):
print(f" Bài {i}: {d}")
# List comprehension: tạo list nhanh
binh_phuong = [x * x for x in range(1, 8)]
diem_dat = [d for d in diem if d >= 5]
print("Bình phương:", binh_phuong)
print("Điểm đạt:", diem_dat)
# List lồng nhau (ma trận)
ma_tran = [[1, 2, 3], [4, 5, 6]]
print("Phần tử hàng 2 cột 3:", ma_tran[1][2])
# Cẩn thận: gán list là dùng CHUNG, muốn sao chép dùng .copy()
a = [1, 2, 3]
b = a
c = a.copy()
a.append(4)
print("a =", a, "| b (dùng chung) =", b, "| c (bản sao) =", c)
# Tuple: giống list nhưng KHÔNG sửa được – dùng cho dữ liệu cố định
toa_do = (21.0285, 105.8542)
vi_do, kinh_do = toa_do # tách tuple
print(f"Hà Nội: vĩ độ {vi_do}, kinh độ {kinh_do}")
# toa_do[0] = 0 -> lỗi
python 07-list-tuple.pyDanh sách điểm: [8, 6.5, 9, 7, 5.5] Phần tử đầu: 8 | cuối: 5.5 | 3 phần tử đầu: [8, 6.5, 9] Số phần tử: 5 | tổng: 36.0 | lớn nhất: 9 | nhỏ nhất: 5.5 Trung bình: 7.2 Sau khi sửa: [4, 8, 7.5, 9, 7] | vừa lấy ra: 10 sorted (tạo list mới): [4, 7, 7.5, 8, 9] sort giảm dần: [9, 8, 7.5, 7, 4] Bài 1: 9 Bài 2: 8 Bài 3: 7.5 Bài 4: 7 Bài 5: 4 Bình phương: [1, 4, 9, 16, 25, 36, 49] Điểm đạt: [9, 8, 7.5, 7] Phần tử hàng 2 cột 3: 6 a = [1, 2, 3, 4] | b (dùng chung) = [1, 2, 3, 4] | c (bản sao) = [1, 2, 3] Hà Nội: vĩ độ 21.0285, kinh độ 105.8542
Giải thích
sort()sửa ngay list;sorted()tạo list mới.[x*x for x in range(1, 8)]— list comprehension, gọn hơn vòng for + append.b = akhông sao chép: a và b là cùng một list. Dùnga.copy().- Tuple dùng cho dữ liệu không đổi như toạ độ, ngày tháng.
✎Bài tập về nhà
📖 Từ điển (dict) và tập hợp (set)
Tổ chức dữ liệu theo khoá – giá trị, đếm tần suất, dùng phép toán tập hợp.
- Tạo, đọc, sửa dict; duyệt items()
- Đếm tần suất bằng dict
- List các dict như một bảng dữ liệu
- Set và phép giao, hợp, hiệu
1Dict và set
# Dictionary (từ điển) và set (tập hợp)
# ----- dict: cặp khoá -> giá trị -----
hoc_sinh = {"ten": "An", "lop": "7A", "diem": 8.5}
print(hoc_sinh["ten"], "học lớp", hoc_sinh["lop"])
hoc_sinh["diem"] = 9 # sửa
hoc_sinh["so_thich"] = "robot" # thêm khoá mới
print(hoc_sinh)
print("Có khoá 'email'?", "email" in hoc_sinh, "| get với giá trị mặc định:", hoc_sinh.get("email", "chưa có"))
for khoa, gia_tri in hoc_sinh.items():
print(f" {khoa:<9}: {gia_tri}")
# Đếm tần suất từ – ứng dụng kinh điển của dict
van_ban = "học học nữa học mãi robot robot code"
dem = {}
for tu in van_ban.split():
dem[tu] = dem.get(tu, 0) + 1
print("Tần suất:", dem)
pho_bien = max(dem, key=dem.get)
print("Từ xuất hiện nhiều nhất:", pho_bien, "-", dem[pho_bien], "lần")
# Danh sách các dict: bảng dữ liệu
lop = [
{"ten": "An", "diem": 8.5},
{"ten": "Bình", "diem": 6.0},
{"ten": "Chi", "diem": 9.2},
]
lop.sort(key=lambda h: h["diem"], reverse=True)
print("Xếp hạng:", [h["ten"] for h in lop])
# Dict comprehension
binh_phuong = {x: x * x for x in range(1, 6)}
print("Bảng bình phương:", binh_phuong)
# ----- set: không trùng lặp, không thứ tự -----
mau = {"đỏ", "xanh", "đỏ", "vàng"}
print("Set tự bỏ trùng:", sorted(mau))
clb_robot = {"An", "Bình", "Chi", "Dũng"}
clb_tin = {"Chi", "Dũng", "Giang"}
print("Tham gia cả hai CLB:", sorted(clb_robot & clb_tin))
print("Tham gia ít nhất 1:", sorted(clb_robot | clb_tin))
print("Chỉ CLB robot:", sorted(clb_robot - clb_tin))
print("Lọc trùng trong list:", sorted(set([3, 1, 3, 2, 1])))
python 08-dict-set.pyAn học lớp 7A
{'ten': 'An', 'lop': '7A', 'diem': 9, 'so_thich': 'robot'}
Có khoá 'email'? False | get với giá trị mặc định: chưa có
ten : An
lop : 7A
diem : 9
so_thich : robot
Tần suất: {'học': 3, 'nữa': 1, 'mãi': 1, 'robot': 2, 'code': 1}
Từ xuất hiện nhiều nhất: học - 3 lần
Xếp hạng: ['Chi', 'An', 'Bình']
Bảng bình phương: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Set tự bỏ trùng: ['vàng', 'xanh', 'đỏ']
Tham gia cả hai CLB: ['Chi', 'Dũng']
Tham gia ít nhất 1: ['An', 'Bình', 'Chi', 'Dũng', 'Giang']
Chỉ CLB robot: ['An', 'Bình']
Lọc trùng trong list: [1, 2, 3]Giải thích
d.get(k, mac_dinh)không lỗi khi khoá chưa có — rất hợp để đếm.max(dem, key=dem.get)tìm khoá có giá trị lớn nhất.key=lambda h: h["diem"]sắp xếp danh sách học sinh theo điểm.- Set tự bỏ phần tử trùng;
&giao,|hợp,-hiệu.
✎Bài tập về nhà
🧩 Hàm (function)
Chia chương trình thành các hàm nhỏ, dễ đọc, dùng lại được.
- def, tham số, return
- Tham số mặc định, gọi theo tên, *args
- Phạm vi biến, global
- lambda và đệ quy
1Định nghĩa và gọi hàm
# Hàm: định nghĩa, tham số, giá trị trả về, phạm vi biến, lambda, đệ quy
def chao(ten):
"""Hàm in lời chào (dòng này là docstring – mô tả hàm)."""
print(f"Xin chào {ten}!")
def dien_tich_hcn(dai, rong):
return dai * rong # return trả kết quả về nơi gọi
def xep_loai(diem, nguong_gioi=8): # tham số có giá trị mặc định
return "Giỏi" if diem >= nguong_gioi else "Chưa giỏi"
def thong_ke(ds):
return min(ds), max(ds), sum(ds) / len(ds) # trả về nhiều giá trị (thực chất là tuple)
def tong_tat_ca(*cac_so): # nhận bao nhiêu số cũng được
return sum(cac_so)
chao("Minh")
print("Diện tích 5 x 3 =", dien_tich_hcn(5, 3))
print("Gọi theo tên tham số:", dien_tich_hcn(rong=2, dai=10))
print(xep_loai(8.5), "|", xep_loai(8.5, nguong_gioi=9))
nho, lon, tb = thong_ke([7, 9, 5, 8])
print(f"min={nho}, max={lon}, tb={tb}")
print("tong_tat_ca(1, 2, 3, 4) =", tong_tat_ca(1, 2, 3, 4))
# ----- Phạm vi biến -----
dem = 0 # biến toàn cục
def tang():
global dem # muốn sửa biến toàn cục phải khai báo global
dem += 1
tang(); tang()
print("dem =", dem)
# ----- Hàm là giá trị: truyền hàm vào hàm khác, lambda -----
def ap_dung(f, x):
return f(x)
print("ap_dung(abs, -5) =", ap_dung(abs, -5))
print("ap_dung(lambda x: x ** 3, 2) =", ap_dung(lambda x: x ** 3, 2))
ten = ["chi", "An", "bình"]
print("Sắp xếp không phân biệt hoa thường:", sorted(ten, key=lambda t: t.lower()))
# ----- Đệ quy -----
def giai_thua(n):
return 1 if n <= 1 else n * giai_thua(n - 1)
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
print("5! =", giai_thua(5), "| 10 số Fibonacci:", [fibonacci(i) for i in range(10)])
print("Docstring của chao:", chao.__doc__)
python 09-ham.pyXin chào Minh! Diện tích 5 x 3 = 15 Gọi theo tên tham số: 20 Giỏi | Chưa giỏi min=5, max=9, tb=7.25 tong_tat_ca(1, 2, 3, 4) = 10 dem = 2 ap_dung(abs, -5) = 5 ap_dung(lambda x: x ** 3, 2) = 8 Sắp xếp không phân biệt hoa thường: ['An', 'bình', 'chi'] 5! = 120 | 10 số Fibonacci: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] Docstring của chao: Hàm in lời chào (dòng này là docstring – mô tả hàm).
Giải thích
- Hàm không có
returnsẽ trả vềNone. return a, b, ctrả về một tuple, nhận bằngx, y, z = ham().- Biến tạo trong hàm là biến cục bộ; tránh dùng
globalkhi không cần — truyền tham số và trả kết quả thì rõ ràng hơn. - Docstring (chuỗi ngay dưới def) mô tả hàm; xem bằng
help(ten_ham).
✎Bài tập về nhà
💾 Module và đọc/ghi file
Dùng thư viện có sẵn và lưu dữ liệu ra file để không mất khi tắt chương trình.
- import module: math, random, datetime, statistics, csv, json
- Đọc/ghi file văn bản với with open()
- Làm việc với file CSV
- Cài thư viện ngoài bằng pip
1Module có sẵn và file
import ten_module rồi dùng ten_module.ham(); hoặc from module import ham. Tự tạo module: lưu các hàm vào tien_ich.py, ở file khác viết import tien_ich. Thư viện ngoài cài bằng lệnh pip install ten_thu_vien (ví dụ pip install numpy).
| Chế độ open() | Ý nghĩa |
|---|---|
"r" | đọc (mặc định) |
"w" | ghi mới (xoá nội dung cũ) |
"a" | ghi thêm vào cuối |
# Module có sẵn (math, random, datetime, statistics) và đọc/ghi file
import math
import random
import statistics
from datetime import date, timedelta
import csv
# ----- math -----
print("math.pi =", round(math.pi, 5), "| sqrt(2) =", round(math.sqrt(2), 4), "| sin(30°) =", round(math.sin(math.radians(30)), 2))
# ----- random (seed để kết quả cố định) -----
random.seed(1)
print("Số ngẫu nhiên 1-6:", [random.randint(1, 6) for _ in range(5)])
print("Chọn ngẫu nhiên người trực nhật:", random.choice(["An", "Bình", "Chi", "Dũng"]))
# ----- datetime -----
ngay_thi = date(2026, 11, 15)
hom_nay = date(2026, 10, 10)
print(f"Còn {(ngay_thi - hom_nay).days} ngày tới ngày thi; 30 ngày nữa là {(hom_nay + timedelta(days=30)):%d/%m/%Y}")
# ----- Ghi file văn bản -----
with open("nhat_ky.txt", "w", encoding="utf-8") as f: # with: tự đóng file khi xong
f.write("Buổi 1: học print\n")
f.write("Buổi 2: học biến\n")
with open("nhat_ky.txt", "a", encoding="utf-8") as f: # "a": ghi thêm vào cuối
f.write("Buổi 3: học vòng lặp\n")
with open("nhat_ky.txt", encoding="utf-8") as f:
for i, dong in enumerate(f, 1):
print(f" dòng {i}: {dong.strip()}")
# ----- File CSV (mở được bằng Excel) -----
du_lieu = [("ten", "toan", "tin"), ("An", 8, 9), ("Bình", 6, 7), ("Chi", 9, 10)]
with open("diem.csv", "w", newline="", encoding="utf-8") as f:
csv.writer(f).writerows(du_lieu)
with open("diem.csv", encoding="utf-8") as f:
bang = list(csv.DictReader(f))
for h in bang:
tb = (int(h["toan"]) + int(h["tin"])) / 2
print(f" {h['ten']}: trung bình {tb}")
print("Trung vị điểm Tin:", statistics.median(int(h["tin"]) for h in bang))
python 10-module-file.pymath.pi = 3.14159 | sqrt(2) = 1.4142 | sin(30°) = 0.5 Số ngẫu nhiên 1-6: [2, 5, 1, 3, 1] Chọn ngẫu nhiên người trực nhật: Dũng Còn 36 ngày tới ngày thi; 30 ngày nữa là 09/11/2026 dòng 1: Buổi 1: học print dòng 2: Buổi 2: học biến dòng 3: Buổi 3: học vòng lặp An: trung bình 8.5 Bình: trung bình 6.5 Chi: trung bình 9.5 Trung vị điểm Tin: 9
Giải thích
with open(...) as f:tự đóng file khi xong, kể cả khi có lỗi.- Luôn ghi
encoding="utf-8"để tiếng Việt không bị lỗi. - File CSV mở được bằng Excel — cách lưu dữ liệu cảm biến, điểm số đơn giản nhất.
✎Bài tập về nhà
🛡️ Xử lý lỗi và lập trình hướng đối tượng
Viết chương trình không “sập” khi người dùng nhập sai, và làm quen với lớp/đối tượng.
- Đọc traceback để tìm lỗi
- try / except / else / finally, raise
- Tạo lớp với __init__, phương thức, __str__
- Kế thừa và ghi đè
1Xử lý lỗi
Đọc traceback từ dưới lên: dòng cuối cho biết loại lỗi và lý do, dòng phía trên cho biết file và số dòng gây lỗi.
# Xử lý lỗi với try / except / else / finally và tự báo lỗi bằng raise
# Đọc thông báo lỗi (traceback) – lỗi KHÔNG được xử lý sẽ dừng chương trình:
# ZeroDivisionError, ValueError, IndexError, KeyError, TypeError, FileNotFoundError...
def chia(a, b):
try:
kq = a / b
except ZeroDivisionError:
print(f" Không chia {a} cho 0 được!")
return None
else: # chạy khi KHÔNG có lỗi
return kq
finally: # luôn chạy (dọn dẹp)
print(f" (đã thử chia {a} / {b})")
print("10 / 4 =", chia(10, 4))
print("10 / 0 =", chia(10, 0))
# Nhập lại tới khi đúng – mẫu rất hay dùng
du_lieu_nhap = ["mười", "", "15"] # giả lập người dùng gõ sai 2 lần
for chuoi in du_lieu_nhap:
try:
tuoi = int(chuoi)
print("Tuổi hợp lệ:", tuoi)
break
except ValueError:
print(f"'{chuoi}' không phải số, nhập lại!")
# Bắt nhiều loại lỗi
ds = [1, 2, 3]
tu_dien = {"a": 1}
for thu in ["ds[5]", "tu_dien['b']", "'5' + 5"]:
try:
eval(thu)
except (IndexError, KeyError) as loi:
print(f"{thu}: lỗi tra cứu -> {type(loi).__name__}: {loi}")
except Exception as loi:
print(f"{thu}: lỗi khác -> {type(loi).__name__}: {loi}")
# Tự báo lỗi khi dữ liệu không hợp lệ
def dat_toc_do(v):
if not 0 <= v <= 255:
raise ValueError(f"tốc độ phải trong 0..255, nhận được {v}")
print("Đặt tốc độ động cơ:", v)
for v in (120, 300):
try:
dat_toc_do(v)
except ValueError as loi:
print("Bắt được lỗi:", loi)
print("\nLỗi không được bắt sẽ in traceback và dừng chương trình:")
int("abc")
print("Dòng này không bao giờ chạy")
python 11a-xu-ly-loi.py(đã thử chia 10 / 4) 10 / 4 = 2.5 Không chia 10 cho 0 được! (đã thử chia 10 / 0) 10 / 0 = None 'mười' không phải số, nhập lại! '' không phải số, nhập lại! Tuổi hợp lệ: 15 ds[5]: lỗi tra cứu -> IndexError: list index out of range tu_dien['b']: lỗi tra cứu -> KeyError: 'b' '5' + 5: lỗi khác -> TypeError: can only concatenate str (not "int") to str Đặt tốc độ động cơ: 120 Bắt được lỗi: tốc độ phải trong 0..255, nhận được 300 Lỗi không được bắt sẽ in traceback và dừng chương trình: Traceback (most recent call last): File "11a-xu-ly-loi.py", line 57, in <module> ValueError: invalid literal for int() with base 10: 'abc'
Giải thích
- Chỉ bắt loại lỗi bạn biết cách xử lý;
except Exceptionchung chung dễ che giấu lỗi thật. - Dòng cuối cố ý gây lỗi để thấy traceback thật trông thế nào — chương trình dừng ngay tại đó.
2Lớp và đối tượng
# Lập trình hướng đối tượng cơ bản: class, __init__, phương thức, kế thừa
class HocSinh:
truong = "THCS Bách Khoa" # thuộc tính chung của lớp
def __init__(self, ten, lop): # hàm khởi tạo, chạy khi tạo đối tượng
self.ten = ten # self = chính đối tượng đang tạo
self.lop = lop
self.diem = []
def them_diem(self, d):
if 0 <= d <= 10:
self.diem.append(d)
def diem_tb(self):
return round(sum(self.diem) / len(self.diem), 2) if self.diem else 0
def __str__(self): # quy định cách in đối tượng
return f"{self.ten} ({self.lop}) – TB {self.diem_tb()}"
an = HocSinh("An", "7A")
chi = HocSinh("Chi", "7B")
for d in (8, 9, 7.5, 12): # 12 bị bỏ qua vì không hợp lệ
an.them_diem(d)
chi.them_diem(10)
print(an)
print(chi)
print("Trường:", an.truong, "| điểm của An:", an.diem)
# ----- Kế thừa: lớp con dùng lại và mở rộng lớp cha -----
class ThietBi:
def __init__(self, ten):
self.ten = ten
self.bat = False
def bat_tat(self):
self.bat = not self.bat
print(f"{self.ten}: {'BẬT' if self.bat else 'TẮT'}")
class Quat(ThietBi):
def __init__(self, ten, so=1):
super().__init__(ten) # gọi khởi tạo của lớp cha
self.so = so
def doi_so(self, so):
self.so = so
print(f"{self.ten}: số {so}")
class Den(ThietBi):
def bat_tat(self): # ghi đè (override) hành vi của lớp cha
super().bat_tat()
print(f" -> đèn {'sáng' if self.bat else 'tối'}")
nha = [Den("Đèn phòng khách"), Quat("Quạt trần", 2)]
for tb in nha: # đa hình: cùng gọi bat_tat()
tb.bat_tat()
nha[1].doi_so(3)
print("Quạt là ThietBi?", isinstance(nha[1], ThietBi))
python 11b-lop-doi-tuong.pyAn (7A) – TB 8.17 Chi (7B) – TB 10.0 Trường: THCS Bách Khoa | điểm của An: [8, 9, 7.5] Đèn phòng khách: BẬT -> đèn sáng Quạt trần: BẬT Quạt trần: số 3 Quạt là ThietBi? True
Giải thích
selflà đối tượng hiện tại; mọi phương thức đều nhậnselflà tham số đầu tiên.__str__quy định nội dung khiprint(doi_tuong).super()gọi phương thức của lớp cha.
✎Bài tập về nhà
🏁 Dự án: chương trình sổ điểm có menu
Tổng hợp toàn bộ kiến thức trong một chương trình hoàn chỉnh có menu, kiểm tra dữ liệu và lưu file.
- Thiết kế chương trình theo các hàm nhỏ
- Dùng dict lưu dữ liệu, json lưu file
- Xử lý mọi trường hợp nhập sai
1Sổ điểm
# DỰ ÁN: Chương trình sổ điểm có menu – tổng hợp biến, điều kiện, vòng lặp, list, dict, hàm, file, xử lý lỗi
import json
FILE = "so_diem.json"
so_diem = {} # {tên: [điểm, điểm, ...]}
def tb(ds):
return round(sum(ds) / len(ds), 2) if ds else 0
def them_hoc_sinh():
ten = input(" Tên học sinh: ").strip()
if not ten:
print(" Tên không được trống")
elif ten in so_diem:
print(" Đã có học sinh này")
else:
so_diem[ten] = []
print(f" Đã thêm {ten}")
def nhap_diem():
ten = input(" Tên: ").strip()
if ten not in so_diem:
print(" Không tìm thấy học sinh")
return
try:
d = float(input(" Điểm: "))
if not 0 <= d <= 10:
raise ValueError
so_diem[ten].append(d)
print(f" Đã ghi điểm {d} cho {ten}")
except ValueError:
print(" Điểm phải là số từ 0 đến 10")
def bang_xep_hang():
print(" {:<4}{:<10}{:<18}{}".format("#", "Tên", "Các điểm", "TB"))
xep = sorted(so_diem.items(), key=lambda kv: tb(kv[1]), reverse=True)
for i, (ten, ds) in enumerate(xep, 1):
print(" {:<4}{:<10}{:<18}{}".format(i, ten, ", ".join(map(str, ds)) or "-", tb(ds)))
def luu():
with open(FILE, "w", encoding="utf-8") as f:
json.dump(so_diem, f, ensure_ascii=False)
print(f" Đã lưu {len(so_diem)} học sinh vào {FILE}")
MENU = {"1": ("Thêm học sinh", them_hoc_sinh), "2": ("Nhập điểm", nhap_diem),
"3": ("Bảng xếp hạng", bang_xep_hang), "4": ("Lưu file", luu)}
while True:
print("\n== SỔ ĐIỂM == " + " ".join(f"[{k}] {v[0]}" for k, v in MENU.items()) + " [0] Thoát")
chon = input("Chọn: ").strip()
if chon == "0":
print("Tạm biệt!")
break
if chon in MENU:
MENU[chon][1]()
else:
print(" Lựa chọn không hợp lệ")
python 12-du-an-so-diem.py1 An 1 Chi 1 An 2 An 8.5 2 An 9 2 Chi 11 2 Chi 9.5 2 Dung 3 4 5 0
== SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 1 Tên học sinh: An Đã thêm An == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 1 Tên học sinh: Chi Đã thêm Chi == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 1 Tên học sinh: An Đã có học sinh này == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 2 Tên: An Điểm: 8.5 Đã ghi điểm 8.5 cho An == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 2 Tên: An Điểm: 9 Đã ghi điểm 9.0 cho An == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 2 Tên: Chi Điểm: 11 Điểm phải là số từ 0 đến 10 == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 2 Tên: Chi Điểm: 9.5 Đã ghi điểm 9.5 cho Chi == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 2 Tên: Dung Không tìm thấy học sinh == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 3 # Tên Các điểm TB 1 Chi 9.5 9.5 2 An 8.5, 9.0 8.75 == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 4 Đã lưu 2 học sinh vào so_diem.json == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 5 Lựa chọn không hợp lệ == SỔ ĐIỂM == [1] Thêm học sinh [2] Nhập điểm [3] Bảng xếp hạng [4] Lưu file [0] Thoát Chọn: 0 Tạm biệt!
Giải thích
- Menu là một dict: phím → (tên chức năng, hàm). Thêm chức năng mới chỉ cần thêm một dòng.
- Dữ liệu nhập mẫu cố tình có lỗi (trùng tên, điểm 11, học sinh không tồn tại) để thấy chương trình xử lý đúng.
json.dump(..., ensure_ascii=False)lưu tiếng Việt đọc được trong file.
✓Tóm tắt
- Biến, kiểu, nhập/xuất, điều kiện, vòng lặp là nền tảng của mọi ngôn ngữ.
- list, dict, set giúp tổ chức dữ liệu; hàm và lớp giúp tổ chức chương trình.
- Học tiếp: AI cơ bản (Python + numpy, scikit-learn) hoặc Arduino & ESP32 (có thể lập trình bằng MicroPython).