14857 - Simple Todo List   

Description

With the deadline of the final project creeping closer and closer, an I2P student has completely lost track of what he needs to do. Help him build a simple todo list to keep track of the tasks he needs to complete for this class. ( ̄^ ̄ )ゞ


What You Must Implement

Implement the following:

  • PendingTaskIterator.__init__
    • Build and store the list of pending tasks (in insertion order).
    • The iterator should snapshot the pending tasks at creation time: later ADD or DONE operations on the TaskQueue must not affect an already-created PendingTaskIterator.
  • PendingTaskIterator.__next__
    • Return the next pending task from this list and advance the internal index.
    • The iterator must yield the same task dictionaries (the same dict objects) that are stored in the underlying TaskQueue.
    • Raise StopIteration when there are no more pending tasks.
  • TaskQueue.add_task
    • Append a new task dict with "name" and "done": False to the underlying list.
  • TaskQueue.mark_done
    • mark the earliest added task whose "name" equals name and whose "done" is False, and set that task’s "done" to True. If there is no pending task with that name, do nothing.
  • TaskQueue.__iter__
    • Return a PendingTaskIterator instance for this TaskQueue instead of the default list iterator.

Code Template

class PendingTaskIterator:
    def __init__(self, task_queue):
        self.pending = []
        self.index = 0
        # TODO: fill self.pending with the pending tasks in the correct order

    def __next__(self):
        # TODO:
        raise NotImplementedError

class TaskQueue(list):
    def add_task(self, name):
        # TODO:
        # Append a new task dict to the list.
        raise NotImplementedError

    def mark_done(self, name):
        # TODO:
        # Traverse the underlying list in insertion order
        raise NotImplementedError

    def __iter__(self):
        # TODO:
        # Return a PendingTaskIterator for this TaskQueue
        raise NotImplementedError


""" Do not change the code below """

q = int(input())
tq = TaskQueue()

for _ in range(q):
    op = input().split()

    if op[0] == "ADD":
        name = " ".join(op[1:])
        tq.add_task(name)

    elif op[0] == "DONE":
        name = " ".join(op[1:])
        tq.mark_done(name)

    elif op[0] == "LEN":
        print(len(tq))

    elif op[0] == "PRINTALL":
        print(tq)

    elif op[0] == "PENDING":
        k = int(op[1])
        it = iter(tq)
        for _ in range(k):
            print(next(it))

 

Test cases:

  • Test cases 1-3: Basic tests (ADD, LEN, PRINTALL)
  • Test cases 4-6: Tests using __iter__ (PENDING command)
  • Test cases 7-10: All commands (ADD, DONE, LEN, PRINTALL, PENDING)

Input

  • The first line contains an integer q: the number of operations.
  • Each of the next q lines is one of:
    • ADD name
      Append a new task with the given name to the queue.
    • DONE name
      Mark one task with the given name as done. If no such task exists, do nothing.
      Hint: Do not iterate with for task in self: here, because that will use the overridden iterator.
    • LEN
      Print the total number of tasks stored in the queue (done + not done).
    • PRINTALL
      Print the internal list of tasks directly (using the default string representation).
      This prints all tasks (done + not done) in insertion order.
    • PENDING k
      Use the iterator protocol to iterate over pending tasks only and print the first k of them.

Constraints:

  • 1 ≤ q ≤ 1000

  • 0 ≤ k ≤ current_number_of_pending_tasks

Output

For each following operation, output the corresponding text:

  • LEN: Print the total number of tasks
  • PRINTALL: Print the the internal list of tasks using default string representation.
  • PENDING k: Print the first k pending tasks.

Sample Input  Download

Sample Output  Download




Discuss