Giải Tin Học 10 trang 132
Lời giải chi tiết SGK Lớp 10 · Môn Tin Há»c · Trang 132–136
Bài 27: Tham số của hàm
🔍 Kiến thức cần nhớ
Tham số (parameter) và đối số (argument)
- Tham số là các biến được khai báo trong dấu ngoặc khi định nghĩa hàm. Trong thân hàm, tham số được dùng như biến.
- Đối số là giá trị cụ thể được truyền vào khi gọi hàm.
- Khi gọi hàm, các tham số sẽ được truyền bằng giá trị thông qua đối số.
Ví dụ:
def f(a, b, c): # a, b, c là tham số
return a + b + c
f(1, 2, 3) # 1, 2, 3 là đối số → kết quả 6
💡 Mẹo nhớ: Tham số nằm ở định nghĩa hàm (def), đối số nằm ở lời gọi hàm. "Tham số là khuôn, đối số là giá trị đổ vào khuôn."
Quy tắc quan trọng: Số lượng đối số khi gọi hàm phải bằng số lượng tham số trong khai báo, nếu không Python sẽ báo lỗi.
Chương trình con (hàm)
Việc chia một bài toán lớn thành các hàm nhỏ giúp:
- Chương trình có cấu trúc rõ ràng, dễ đọc, dễ hiểu.
- Dễ hiệu chỉnh, phát triển và nâng cấp.
- Tái sử dụng được đoạn lệnh lặp đi lặp lại nhiều lần.
- Phát huy tinh thần làm việc nhóm (mỗi người viết một hàm).
⚠️ Lưu ý thi: Gọi hàm sai số đối số là lỗi rất hay gặp. Luôn đếm kỹ số tham số khi khai báo và số đối số khi gọi.
⚙️ Bài tập
Hoạt động 1 — Phân biệt tham số và đối số (trang 133)
Câu 1
Đề bài: Một hàm khi khai báo có một tham số, nhưng khi gọi hàm có thể có hai đối số được không?
Cách 1 — Dựa vào quy tắc số lượng
Không được. Quy tắc của Python yêu cầu số lượng đối số khi gọi hàm phải bằng đúng số lượng tham số trong khai báo.
Hàm chỉ có một tham số nghĩa là chỉ "nhận" được một giá trị. Nếu truyền hai đối số, Python không biết gán giá trị thứ hai vào đâu.
Cách 2 — Kiểm chứng bằng ví dụ
def f(x):
return x + 1
f(10, 5) # Lỗi: TypeError: f() takes 1 positional argument but 2 were given
Python báo lỗi ngay, khẳng định không thể truyền hai đối số cho hàm chỉ có một tham số.
Câu 2
Đề bài: Giả sử hàm f có hai tham số x, y; khi khai báo hàm sẽ trả lại giá trị x + y. Lời gọi hàm f(a) có lỗi hay không?
Cách 1 — Phân tích số lượng đối số
Có lỗi. Hàm f cần hai đối số (tương ứng hai tham số x và y), nhưng lời gọi f(a) chỉ cung cấp một đối số. Thiếu một đối số nên Python báo lỗi.
Cách 2 — Minh họa
def f(x, y):
return x + y
f(5) # Lỗi: TypeError: f() missing 1 required positional argument: 'y'
💡 Mẹo nhớ: Truyền thừa hay thiếu đối số đều gây lỗi. Số đối số = số tham số.
Hoạt động 2 — Khi nào nên sử dụng chương trình con? (trang 133)
Giả sử đã có hàm kiểm tra số nguyên tố prime(n) trả lại True nếu n là số nguyên tố:
def prime(n):
if n < 2:
return False
c = 0
k = 1
while k <= n:
if n % k == 0:
c = c + 1
k = k + 1
if c == 2: # số nguyên tố có đúng 2 ước: 1 và chính nó
return True
else:
return False
Câu 1
Đề bài: Sử dụng hàm prime, em hãy viết chương trình in ra các số nguyên tố trong khoảng từ m đến n, với m, n là hai số tự nhiên và m < n.
Cách 1 — Duyệt và kiểm tra từng số
m = int(input("Nhập m: "))
n = int(input("Nhập n: "))
print("Các số nguyên tố trong khoảng từ", m, "đến", n, "là:")
for k in range(m, n + 1):
if prime(k):
print(k, end=" ")
Chương trình duyệt mọi số k từ m đến n, gọi hàm prime(k) để kiểm tra, nếu là số nguyên tố thì in ra.
Cách 2 — Gom kết quả vào danh sách
m = int(input("Nhập m: "))
n = int(input("Nhập n: "))
ket_qua = [k for k in range(m, n + 1) if prime(k)]
print("Các số nguyên tố:", ket_qua)
Dùng list comprehension cho gọn, kết quả lưu thành danh sách rồi in một lần.
Câu 2
Đề bài: Em hãy nêu một công việc/bài toán mà có thể sử dụng hàm để giải.
Cách 1 — Nêu ví dụ điển hình
Một số bài toán nên dùng hàm vì có thao tác lặp lại nhiều lần:
- Tính giai thừa n! để dùng trong công thức tổ hợp, chỉnh hợp (cần tính nhiều lần).
- Tính ước chung lớn nhất ƯCLN của hai số, dùng lại khi rút gọn nhiều phân số.
- Kiểm tra một số có phải số chính phương hay không.
- Đảo ngược một xâu ký tự hoặc kiểm tra xâu đối xứng (palindrome).
Đặc điểm chung: công việc đó được lặp lại nhiều lần với các giá trị khác nhau, nên tách thành hàm sẽ làm chương trình ngắn gọn, rõ ràng.
💡 Mẹo nhớ: Khi thấy một đoạn lệnh phải viết đi viết lại → đó là dấu hiệu nên đưa vào một hàm.
THỰC HÀNH (trang 135 – 136)
Nhiệm vụ 1
Đề bài: Thiết lập hàm f(A, b) tính tổng các số của danh sách A theo quy định:
- Nếu b = 0 thì tính tổng tất cả các số của danh sách A.
- Nếu b khác 0 thì chỉ tính tổng các số dương của A.
Cách 1 — Kiểm tra giá trị b trong mỗi vòng lặp (theo SGK)
def f(A, b):
S = 0
for x in A:
if b == 0:
S = S + x # cộng tất cả các số
else:
if x > 0:
S = S + x # chỉ cộng số dương
return S
# Thử nghiệm
A = [10, 2, -1, 5, 10, -3]
print(f(A, 0)) # 23 (cộng tất cả)
print(f(A, 1)) # 27 (chỉ cộng các số dương: 10+2+5+10)
Cách 2 — Tách điều kiện ra trước, gọn hơn
def f(A, b):
if b == 0:
return sum(A) # tổng tất cả
else:
return sum(x for x in A if x > 0) # tổng các số dương
Cách này dùng hàm sum có sẵn nên ngắn gọn, dễ đọc hơn.
Nhiệm vụ 2
Đề bài: Thiết lập hàm f(s, g) đếm số các từ của một xâu s, với ký tự tách từ là g.
Ví dụ:
- f("Hà Nội", " ") trả lại giá trị 2
- f("Hà Nội", "-") trả lại giá trị 1
Cách 1 — Dùng phương thức split (theo gợi ý SGK)
Lệnh s.split(g) tách xâu s thành danh sách các từ dựa theo ký tự ngăn cách g. Đếm số phần tử của danh sách là được số từ.
def f(s, g):
danh_sach = s.split(g)
return len(danh_sach)
# Thử nghiệm
print(f("Hà Nội", " ")) # 2
print(f("Hà Nội", "-")) # 1
Cách 2 — Đếm số ký tự ngăn cách
Nếu một dòng chữ có k từ thì giữa chúng có k - 1 ký tự ngăn cách. Đếm số ký tự g rồi cộng 1:
def f(s, g):
return s.count(g) + 1
⚠️ Lưu ý thi: Cách 2 chỉ đúng khi các từ không bị ngăn cách bởi nhiều ký tự g liên tiếp. Cách 1 (split) an toàn và chuẩn hơn.
Nhiệm vụ 3
Đề bài: Thiết lập hàm f(s1, s2) với s1, s2 là hai xâu cần gộp. Hàm gộp hai xâu theo cách lấy lần lượt từng ký tự của s1, s2 đưa vào xâu kết quả. Nếu một xâu hết ký tự thì đưa phần còn lại của xâu dài hơn vào kết quả.
Ví dụ: nếu s1 = "1111", s2 = "0000" thì xâu kết quả là "10101010".
Cách 1 — Theo hướng dẫn SGK
def f(s1, s2):
S = ""
n1 = len(s1)
n2 = len(s2)
n = min(n1, n2)
# Đan xen các ký tự trong phần chung
for i in range(n):
S = S + s1[i] + s2[i]
# Nếu s1 dài hơn, thêm phần đuôi của s1
if n1 > n2:
for i in range(n2, n1):
S = S + s1[i]
# Nếu s2 dài hơn, thêm phần đuôi của s2
if n2 > n1:
for i in range(n1, n2):
S = S + s2[i]
return S
# Thử nghiệm
print(f("1111", "0000")) # 10101010
print(f("abc", "12345")) # a1b2c345
Cách 2 — Dùng phép cắt xâu (slicing)
def f(s1, s2):
n = min(len(s1), len(s2))
S = ""
for i in range(n):
S = S + s1[i] + s2[i]
S = S + s1[n:] + s2[n:] # nối phần đuôi còn lại (một trong hai sẽ rỗng)
return S
Vì khi cắt từ vị trí n trở đi, xâu ngắn hơn sẽ cho phần rỗng, nên chỉ phần đuôi của xâu dài được nối thêm. Cách này ngắn gọn hơn.
LUYỆN TẬP (trang 136)
Câu 1
Đề bài: Thiết lập hàm f(a, b, c) với a, b, c là số nguyên. Hàm trả lại giá trị (a + b + c).
Cách 1 — Trực tiếp
def f(a, b, c):
return a + b + c
# Thử nghiệm
print(f(1, 2, 3)) # 6
print(f(-5, 10, 2)) # 7
Cách 2 — Tính qua biến trung gian (dễ mở rộng kiểm tra)
def f(a, b, c):
tong = a + b + c
return tong
Hai cách cho kết quả như nhau; cách 1 ngắn gọn nhất.
Câu 2
Đề bài: Viết chương trình: Nhập n số tự nhiên từ bàn phím (hai số cách nhau bởi dấu cách). Tính và in ra tổng của các số này.
Cách 1 — Tách xâu rồi cộng từng số
s = input("Nhập các số (cách nhau bởi dấu cách): ")
danh_sach = s.split() # tách thành danh sách các xâu số
tong = 0
for x in danh_sach:
tong = tong + int(x) # đổi sang số nguyên rồi cộng
print("Tổng của các số là:", tong)
Cách 2 — Dùng map và sum
s = input("Nhập các số (cách nhau bởi dấu cách): ")
cac_so = list(map(int, s.split())) # đổi tất cả sang số nguyên
print("Tổng của các số là:", sum(cac_so))
💡 Mẹo nhớ:s.split()không có tham số sẽ tự tách theo dấu cách (kể cả nhiều dấu cách liền nhau).map(int, ...)đổi cả danh sách xâu sang số nguyên một lần.
VẬN DỤNG (trang 136)
Câu 1
Đề bài: Viết chương trình: Nhập hai số tự nhiên từ bàn phím (hai số cách nhau bởi dấu phẩy), in ra ước chung lớn nhất (ƯCLN) của hai số.
Cách 1 — Thuật toán Euclid bằng phép trừ
def UCLN(a, b):
while a != b:
if a > b:
a = a - b
else:
b = b - a
return a
s = input("Nhập hai số cách nhau bởi dấu phẩy: ")
x, y = s.split(",") # tách theo dấu phẩy
a = int(x)
b = int(y)
print("ƯCLN của", a, "và", b, "là:", UCLN(a, b))
Cách 2 — Thuật toán Euclid bằng phép chia lấy dư (nhanh hơn)
def UCLN(a, b):
while b != 0:
a, b = b, a % b # gán đồng thời
return a
s = input("Nhập hai số cách nhau bởi dấu phẩy: ")
a, b = map(int, s.split(","))
print("ƯCLN:", UCLN(a, b))
💡 Mẹo nhớ: Thuật toán Euclid bằng phép chia dư rất nhanh: lặp lại "lấy số bé và phần dư" cho đến khi dư bằng 0, số còn lại là ƯCLN.
⚠️ Lưu ý thi: Đề yêu cầu tách bằng dấu phẩy nên phải dùngsplit(","), không phảisplit()mặc định.
Câu 2
Đề bài: Thiết lập hàm f(x, c) có hai tham số là xâu x và số c. Hàm trả lại xâu ký tự x in hoa nếu c = 1; nếu c khác 1 thì trả lại xâu x in thường.
Gợi ý: Dùng phương thức upper và lower để chuyển ký tự sang chữ in hoa và in thường.
Cách 1 — Dùng cấu trúc if … else (theo gợi ý SGK)
def f(x, c):
if c == 1:
return x.upper() # chuyển sang chữ in hoa
else:
return x.lower() # chuyển sang chữ in thường
# Thử nghiệm
print(f("Ha Noi", 1)) # HA NOI
print(f("Ha Noi", 0)) # ha noi
Cách 2 — Dùng biểu thức điều kiện một dòng
def f(x, c):
return x.upper() if c == 1 else x.lower()
Cách 2 viết gọn trên một dòng, dùng cú pháp giá_trị_1 if điều_kiện else giá_trị_2.
💡 Mẹo nhớ:upper()→ chữ in HOA,lower()→ chữ in thường. Cả hai đều trả về xâu mới, không làm thay đổi xâu gốc.
🎯 Ghi nhớ: - Tham số ở phần định nghĩa hàm, đối số ở lời gọi hàm; số lượng phải khớp nhau, nếu không sẽ báo lỗi. - Đối số truyền giá trị vào hàm theo đúng thứ tự tham số. - Chương trình con (hàm) giúp chia bài toán lớn thành các bài toán nhỏ: chương trình rõ ràng, dễ hiểu, dễ sửa và tái sử dụng được. - Nhớ các phương thức xử lý xâu thường dùng:split()(tách),upper()/lower()(in hoa/thường),count()(đếm),len()(độ dài).
