DHDataHọc
QuizLesson 6/304 min read+10 XP

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:

code
name = input("Tên: ")
year = int(input("Năm sinh: "))
print(f"Chào {name}, bạn {2026 - year} tuổi")

Chạy:

code
Tên: An
Năm sinh: 1998
Chào An, bạn 28 tuổi

Ba dòng, nhưng chứa bốn khái niệm của chương này:

DòngKhá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 - yearSố 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:

code
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:

code
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))
code
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ổi

Hà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ỏ:

code
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:

code
Năm sinh: abc
ValueError: invalid literal for int() with base 10: 'abc'

Bản an toàn:

code
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ử:

code
'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ổi

Bốn lớp bảo vệ:

  1. .strip() bỏ khoảng trắng hai đầu tên; nếu rỗng thì thay bằng "bạn".
  2. try/except ValueError bắt chuỗi không phải số.
  3. Kiểm tra khoảng 1900 <= year <= current loại năm vô lý.
  4. 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:

code
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ùng

f-string cho phép định dạng ngay trong dấu ngoặc:

code
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

  1. Chạy chương trình tối giản với tên và năm sinh của bạn.
  2. Bỏ int() và đọc lỗi TypeError để nhớ input() trả chuỗi.
  3. Viết hàm chao tách riêng, gọi với ba cặp giá trị khác nhau.
  4. Thêm kiểm tra năm sinh, thử với "abc", "", "2030".
  5. 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".
  6. 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ứngNguyên nhânCá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àotry/except ValueError
Tuổi âm hoặc 2000Không kiểm tra khoảng nămGiới hạn 1900..năm hiện tại
Tên có khoảng trắng thừaKhông .strip()Chuẩn hoá trước khi dùng
In ra NoneHàm không return, chỉ printTrả giá trị từ hàm
Chạy khi importThiếu if __name__ == "__main__"Bọc phần nhập liệu
Tuổi lệch mộtChưa tính sinh nhậtGhi "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 ValueError và 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