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.
-
Define a
TaskStatusenum with membersplanned,in_progress,blocked, anddone. UseStrEnumso the values are strings.Pythonfrom enum import StrEnum class TaskStatus(StrEnum): planned = "planned" in_progress = "in_progress" blocked = "blocked" done = "done" -
Write
is_overdue(due_date, status)that returnsTrueonly when the task has a due date, isn't done, and the due date is in the past. Otherwise returnFalse.Pythondef is_overdue(due_date, status): pass -
Write
next_status(current)that advances the task's state.plannedbecomesin_progress,in_progressbecomesdone, anddoneandblockedstay where they are.Pythondef next_status(current): match current: case TaskStatus.planned: pass # TODO case TaskStatus.in_progress: pass # TODO case TaskStatus.done | TaskStatus.blocked: pass # TODO -
Put this at bottom of to call the sample inputs and prints the results.
Pythonfrom 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
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