Tháng phải hợp lệ trước khi lấy số ngày
Năm dương lịch nhuận khi chia hết cho 400, hoặc chia hết cho 4 mà không chia hết cho 100. Ví dụ 2024 nhuận, 2023 không nhuận, 1900 không nhuận, 2000 nhuận. Tháng 2 có 29 ngày trong năm nhuận, 28 ngày trong năm thường. Chỉ số `thang-1` chỉ dùng được **sau khi** xác nhận tháng từ 1 đến 12; năm phải từ 1 trở lên.
Nhiệm vụ: lưu `kiem-ngay.py`, chạy năm bộ ngày mẫu và đối chiếu `True`/`False`:
```python
def nhuan(nam):
return nam % 400 == 0 or (nam % 4 == 0 and nam % 100 != 0)
def hop_le(ngay, thang, nam):
if nam < 1 or thang < 1 or thang > 12:
return False
so_ngay = [31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
if nhuan(nam):
so_ngay[1] = 29
return 1 <= ngay <= so_ngay[thang - 1]
for ngay_thang_nam in [(29, 2, 2024), (29, 2, 2023),
(31, 4, 2025), (31, 12, 2025), (1, 0, 2025)]:
print(ngay_thang_nam, hop_le(*ngay_thang_nam))
```
Kết quả lần lượt là `True`, `False`, `False`, `True`, `False`. Danh sách số ngày được tạo **mới trong mỗi lời gọi**, nên thử năm nhuận không làm tháng 2 của lần gọi năm thường thành 29. Nếu bài nhận xâu dạng `ngày-tháng-năm`, cần kiểm có đúng ba phần và đổi được thành số trước khi gọi hàm; mã trên dùng sẵn bộ ba số để tập trung vào quy tắc ngày.
Bài luyện
`hop_le(29, 2, 2024)` trả gì?
2024 chia hết cho 4, không chia hết cho 100; tháng 2 có 29 ngày.
Đây là ngày hợp lệ.
Hàm trả bool.
Tháng 2 có chỉ số hợp lệ.
Lời giải
2024 là năm nhuận theo quy tắc; tháng 2 có 29 ngày. Ngày 29 nằm trong khoảng 1–29, nên hàm trả `True`.
Bài luyện
Vì sao `hop_le` kiểm tháng 1–12 trước biểu thức `so_ngay[thang-1]`?
Bài không tính trọng lượng.
List có 12 phần tử; tháng 0 cho chỉ số -1 hợp cú pháp nhưng sai nghĩa.
Không cần sắp xếp.
Năm nhuận được xét riêng.
Lời giải
Nếu tháng=0, `thang-1=-1` trỏ đến phần tử cuối trong Python; tháng>12 vượt phạm vi. Kiểm tháng trước giúp loại cả hai.
Bài luyện
Vì sao tạo `so_ngay` mới trong mỗi lần gọi `hop_le`?
Mỗi lần gọi bắt đầu từ tháng 2 có 28 ngày rồi sửa thành 29 nếu nhuận.
List có thể sửa.
Chỉ tháng 2 đổi theo nhuận.
Tháng vẫn được kiểm.
Lời giải
List cục bộ mới bắt đầu với tháng 2 là 28. Chỉ lần gọi có năm nhuận mới đổi thành 29, nên các lần gọi không ảnh hưởng nhau.
Bài luyện
Với `(31, 4, 2025)`, kết quả nào đúng?
Không phải tháng nào cũng 31 ngày.
Danh sách ghi tháng 4 có 30 ngày.
Tháng 4 hợp lệ và có chỉ số.
Hàm trả bool.
Lời giải
Tháng 4 có 30 ngày; 31 lớn hơn 30 nên `hop_le(31,4,2025)` trả `False`.
Đang học