Skip to content

Exercise: Basic Python

Build a small module that models task status transitions and overdue checks for a release tracker. Everything fits in a single main.py.

  1. Define a TaskStatus enum with members planned, in_progress, blocked, and done. Use StrEnum so the values are strings.

    Python
    from enum import StrEnum
    
    
    class TaskStatus(StrEnum):
        planned = "planned"
        in_progress = "in_progress"
        blocked = "blocked"
        done = "done"
    
  2. Write is_overdue(due_date, status) that returns True only when the task has a due date, isn't done, and the due date is in the past. Otherwise return False.

    Python
    def is_overdue(due_date, status):
        pass
    
  3. Write next_status(current) that advances the task's state. planned becomes in_progress, in_progress becomes done, and done and blocked stay where they are.

    Python
    def next_status(current):
        match current:
            case TaskStatus.planned:
                pass  # TODO
            case TaskStatus.in_progress:
                pass  # TODO
            case TaskStatus.done | TaskStatus.blocked:
                pass  # TODO
    
  4. Put this at bottom of to call the sample inputs and prints the results.

    Python
    from datetime import date, timedelta
    
    if __name__ == "__main__":
        yesterday = date.today() - timedelta(days=1)
    
        print(is_overdue(None, TaskStatus.planned))  # False
        print(is_overdue(yesterday, TaskStatus.done))  # False
        print(is_overdue(yesterday, TaskStatus.in_progress))  # True
    
        print(next_status(TaskStatus.planned))  # TaskStatus.in_progress
        print(next_status(TaskStatus.in_progress))  # TaskStatus.done
        print(next_status(TaskStatus.done))  # TaskStatus.done
        print(next_status(TaskStatus.blocked))  # TaskStatus.blocked
    

Run the file with uv run main.py and confirm the output matches the comments.

Solution
Python
from datetime import date, timedelta
from enum import StrEnum


class TaskStatus(StrEnum):
    planned = "planned"
    in_progress = "in_progress"
    blocked = "blocked"
    done = "done"


def is_overdue(due_date, status):
    if due_date is None:
        return False
    if status == TaskStatus.done:
        return False
    return due_date < date.today()


def next_status(current):
    match current:
        case TaskStatus.planned:
            return TaskStatus.in_progress
        case TaskStatus.in_progress:
            return TaskStatus.done
        case TaskStatus.done | TaskStatus.blocked:
            return current


if __name__ == "__main__":
    yesterday = date.today() - timedelta(days=1)

    print(is_overdue(None, TaskStatus.planned))  # False
    print(is_overdue(yesterday, TaskStatus.done))  # False
    print(is_overdue(yesterday, TaskStatus.in_progress))  # True

    print(next_status(TaskStatus.planned))  # TaskStatus.in_progress
    print(next_status(TaskStatus.in_progress))  # TaskStatus.done
    print(next_status(TaskStatus.done))  # TaskStatus.done
    print(next_status(TaskStatus.blocked))  # TaskStatus.blocked

Success

If the driver prints the values shown in the comments next to each print call, the enum, conditional, and match-statement work as expected