Bài tập nhỏ
Bạn sẽ học được
- Ghép
input(), ép kiểu và f-string thành một chương trình hoàn chỉnh. - Vì sao
input()luôn trả chuỗi. - Kiểm tra dữ liệu đầu vào trước khi tính toán.
- Xử lý trường hợp năm sinh không hợp lệ.
- Viết hàm tách khỏi phần nhập liệu để dễ kiểm thử.
Khái niệm cốt lõi
Đề bài: nhập tên và năm sinh, in câu chào kèm tuổi ước tính.
Chương trình tối giản:
name = input("Tên: ")
year = int(input("Năm sinh: "))
print(f"Chào {name}, bạn {2026 - year} tuổi")Chạy:
Tên: An
Năm sinh: 1998
Chào An, bạn 28 tuổiBa dòng, nhưng chứa bốn khái niệm của chương này:
| Dòng | Khái niệm |
|---|---|
input(...) | Trả về chuỗi, luôn luôn |
int(...) | Ép chuỗi sang số nguyên, có thể ném ValueError |
2026 - year | Số học trên int |
f"..." | Nội suy giá trị vào chuỗi |
input() trả str kể cả khi người dùng gõ 1998. Nếu quên int(), 2026 - year sẽ ném:
TypeError: unsupported operand type(s) for -: 'int' and 'str'Đây là lỗi số một của người mới khi làm bài tập nhập liệu.
Tách hàm để kiểm thử
Trộn input() và logic trong một khối khiến chương trình khó kiểm thử: mỗi lần chạy phải gõ tay. Tách phần tính toán thành hàm:
def chao(name: str, year: int, current: int = 2026) -> str:
age = current - year
return f"Chào {name}, bạn khoảng {age} tuổi"
print(chao("An", 1998))
print(chao("Bình", 2005))
print(chao("Chi", 2010))Chào An, bạn khoảng 28 tuổi
Chào Bình, bạn khoảng 21 tuổi
Chào Chi, bạn khoảng 16 tuổiHàm nhận dữ liệu qua tham số, trả chuỗi — không đọc bàn phím, không in trực tiếp. Nhờ vậy có thể chạy ba ca kiểm thử trong một lần mà không cần nhập gì. Phần input() chỉ còn là lớp vỏ:
if __name__ == "__main__":
name = input("Tên: ")
year = int(input("Năm sinh: "))
print(chao(name, year))if __name__ == "__main__": bảo đảm phần nhập liệu chỉ chạy khi gọi trực tiếp file, không chạy khi file được import từ nơi khác.
Từ "khoảng" trong câu chào là cố ý: chưa biết sinh nhật đã qua trong năm nay chưa, nên tuổi có thể lệch một. Nếu đề cho cả ngày sinh, mới tính chính xác.
Kiểm tra dữ liệu đầu vào
Chương trình trên vỡ khi người dùng gõ chữ hoặc để trống:
Năm sinh: abc
ValueError: invalid literal for int() with base 10: 'abc'Bản an toàn:
def chao_an_toan(name: str, raw_year: str, current: int = 2026) -> str:
name = name.strip() or "bạn"
try:
year = int(raw_year)
except ValueError:
return "Năm sinh không hợp lệ"
if not 1900 <= year <= current:
return "Năm sinh không hợp lệ"
return f"Chào {name}, bạn khoảng {current - year} tuổi"Chạy thử:
'1998' → Chào An, bạn khoảng 28 tuổi
'abc' → Năm sinh không hợp lệ
'' → Năm sinh không hợp lệ
'2030' → Năm sinh không hợp lệ
' 2000 ' → Chào An, bạn khoảng 26 tuổiBốn lớp bảo vệ:
.strip()bỏ khoảng trắng hai đầu tên; nếu rỗng thì thay bằng "bạn".try/except ValueErrorbắt chuỗi không phải số.- Kiểm tra khoảng
1900 <= year <= currentloại năm vô lý. int()tự bỏ khoảng trắng trong" 2000 "— không cần strip trước.
Lưu ý: int("") ném ValueError nên rơi vào nhánh bắt lỗi, không cần kiểm tra rỗng riêng.
In kết quả
Ba cách in, chọn theo ngữ cảnh:
print("Chào " + name + ", bạn " + str(age) + " tuổi") # nối chuỗi, phải ép kiểu
print("Chào {}, bạn {} tuổi".format(name, age)) # format cũ
print(f"Chào {name}, bạn {age} tuổi") # f-string, nên dùngf-string cho phép định dạng ngay trong dấu ngoặc:
age = 28
print(f"{age:03d}") # 028
print(f"{age:,}") # 28
print(f"{0.1234:.1%}") # 12.3%Với bài này, f-string là lựa chọn rõ ràng nhất.
Thực hành
- Chạy chương trình tối giản với tên và năm sinh của bạn.
- Bỏ
int()và đọc lỗiTypeErrorđể nhớinput()trả chuỗi. - Viết hàm
chaotách riêng, gọi với ba cặp giá trị khác nhau. - Thêm kiểm tra năm sinh, thử với
"abc","","2030". - Thêm câu chào theo buổi: nhận thêm tham số
hour(0–23) và trả "Chào buổi sáng/chiều/tối". - Viết ba ca kiểm thử cho hàm mới mà không cần nhập bàn phím.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
TypeError: unsupported operand ... 'int' and 'str' | Quên int() cho input() | Ép kiểu ngay khi nhập |
ValueError khi nhập chữ | Không kiểm tra đầu vào | try/except ValueError |
| Tuổi âm hoặc 2000 | Không kiểm tra khoảng năm | Giới hạn 1900..năm hiện tại |
| Tên có khoảng trắng thừa | Không .strip() | Chuẩn hoá trước khi dùng |
In ra None | Hàm không return, chỉ print | Trả giá trị từ hàm |
Chạy khi import | Thiếu if __name__ == "__main__" | Bọc phần nhập liệu |
| Tuổi lệch một | Chưa tính sinh nhật | Ghi "khoảng" hoặc nhận thêm ngày sinh |
Tóm tắt
input()luôn trả chuỗi; phải ép kiểu trước khi tính.- Tách logic thành hàm nhận tham số để kiểm thử không cần bàn phím.
- Kiểm tra
ValueErrorvà khoảng hợp lệ cho mọi dữ liệu từ bên ngoài. - f-string là cách in hiện đại, hỗ trợ định dạng số.
- Dùng "khoảng" khi chưa biết sinh nhật, để câu chào trung thực.
Use ← → to move between lessons