python-252Đọc toàn bộ đề miễn phí

Bộ đếm ngược cài `__iter__` và `__next__`

for trong Python không biết gì về danh sách hay chuỗi; nó chỉ gọi hai giao thức:

PythonCơ bản13 phút

Tiến độ của tôi ở bài này

Điểm và code bạn nộp được lưu vào tài khoản sau khi chấm bài.

Đang tải điểm của bạn…

Kiến thức và chủ đề

protocolsiterationdunder-methodsentry-ramp

Kiến thức tiên quyết: python-basics, python-classes-intro, python-loop-basics.

Nội dung đề bài

Mô tả bài toán

for trong Python không biết gì về danh sách hay chuỗi; nó chỉ gọi hai giao thức: iter để lấy đối tượng duyệt và next để lấy từng phần tử, dừng lại khi gặp StopIteration. Bài này tự viết một bộ đếm ngược để thấy rõ hai lời gọi đó.

Yêu cầu

Cài đặt lớp Countdown:

  • init(self, start): nhận số nguyên không âm; ném ValueError nếu start không

phải số nguyên hoặc là số âm. Giá trị này nằm trong self._start.

  • iter(self): đưa bộ đếm về vị trí ban đầu self._start rồi trả về chính đối

tượng (self), để lớp có thể dùng lại nhiều lần trong nhiều vòng for.

  • next(self): trả về số hiện tại rồi giảm đi 1; khi không còn số nào để trả thì

ném StopIteration. Mỗi lượt gọi trả một số int.

  • drain(self): trả về danh sách tất cả số còn lại, bằng list(self).
  • next_value(self): trả về số kế tiếp, tức next(self); có thể ném StopIteration.
  • remaining(self): trả về số hiện tại đang chờ được trả.

Quy ước nộp bài

Nộp lớp Countdown trong solution.py. Hệ thống tự khởi tạo lớp bằng Countdown(start=...), gọi các phương thức trên đối tượng và bắt ngoại lệ ValueError / StopIteration; không dùng stdin/stdout.

Input

Hệ thống khởi tạo lớp bằng tham số từ khoá start, rồi gọi lần lượt các phương thức theo kịch bản của từng bộ test.

Output

Danh sách giá trị trả về theo đúng thứ tự gọi. drain trả về một danh sách số nguyên; nếu một lượt gọi ném StopIteration thì cả bộ test được coi là kịch bản ném lỗi.

Ràng buộc

  • start là int không âm; 3.5 hay -1 đều không hợp lệ.
  • iter phải đặt lại vị trí, nếu không lần duyệt thứ hai sẽ rỗng.
  • next phải ném StopIteration khi start=0 hoặc khi đã đếm hết.

Ví dụ 1

Input

Countdown(init={"start": 3}, methods=[{"method": "drain"}])

Output

[[3, 2, 1]]

Ví dụ 2

Input

Countdown(init={"start": 0}, methods=[{"method": "drain"}, {"method": "remaining"}])

Output

[[], 0]

Giải thích

Countdown(start=3) thì drain() trả [3, 2, 1]. Khi start=2, gọi next_value(), remaining(), drain(), remaining() cho [2, 1, [2, 1], 0] vì drain đặt lại bộ đếm trước khi duyệt.

3 cấp độ gợi ýMở dần khi bạn thật sự cần hỗ trợ.
Phân tích lời giảiGiải thích hướng tư duy và thuật toán.
Code tham khảoDùng để đối chiếu sau khi tự làm.

Gợi ý và lời giải chỉ mở sau khi bạn bấm Nộp bài. Giáo viên và quản trị viên mở được ngay.

Nhóm Zalo