Software Engineer Coding Exercise
Build a task tracking system with task CRUD functionality, priority-ordered retrieval, quota-controlled user assignments with TTLs, and tracking for completed or expired tasks. The exercise is organized in levels, with each level extending the capabilities introduced before it.
Every task has a distinct string task_id, a string name, and an integer priority; larger priority values indicate greater importance. Implement the system progressively through four levels.
Create a TaskManager class that can add, look up, and modify tasks.
class TaskManager:
def __init__(self):
"""Set up the task tracking system."""
pass
def create_task(self, task_id: str, name: str, priority: int) -> bool:
"""
Add a task using the supplied ID, name, and priority.
Args:
task_id: The task's unique identifier.
name: The task title.
priority: Importance of the task; larger means more important.
Returns:
True when the task is added successfully.
False when another task already uses this ID.
"""
pass
def get_task(self, task_id: str) -> str:
"""
Look up a task using its identifier.
Args:
task_id: Identifier of the requested task.
Returns:
A value formatted as "task_id: name (priority P)", with P
replaced by the priority, or "" when no matching task exists.
"""
pass
def update_task(self, task_id: str, name: str, priority: int) -> bool:
"""
Replace the name and priority of an existing task.
Args:
task_id: Identifier of the task being changed.
name: Replacement task name.
priority: Replacement priority value.
Returns:
True if the requested task was changed.
False if no task has that ID.
"""
pass
tm = TaskManager()
tm.create_task("job7", "Plan Sprint", 2) # True
tm.create_task("job8", "Run Checks", 6) # True
tm.create_task("job7", "Repeated Entry", 1) # False (duplicate ID)
tm.get_task("job7") # "job7: Plan Sprint (priority 2)"
tm.get_task("job9") # "" (task is absent)
tm.update_task("job7", "Plan Next Sprint", 4) # True
tm.get_task("job7") # "job7: Plan Next Sprint (priority 4)"
tm.update_task("job9", "Unused", 1) # False (task is absent)
Add support for returning the highest-priority N tasks, with an optional filter that keeps only tasks whose names include a specified substring.
def list_tasks(self, n: int, substr: str = "") -> list:
"""
Produce up to N tasks ordered from greatest priority to least.
A provided substring can restrict the results to tasks whose
names contain that text.
Args:
n: Largest number of tasks that may be returned.
substr: When non-empty, retain only tasks with names that
contain this case-sensitive substring. When empty,
consider every task.
Returns:
Strings formatted as "task_id: name (priority P)", ordered
by descending priority. Equal-priority tasks are ordered by
task_id alphabetically. Return every matching task when fewer
than n tasks match.
"""
pass
tm = TaskManager()
tm.create_task("a1", "Draft Plan", 4)
tm.create_task("a2", "Verify Build", 7)
tm.create_task("a3", "Plan Review", 7)
tm.create_task("a4", "Publish Notes", 1)
tm.list_tasks(3)
# [
# "a2: Verify Build (priority 7)",
# "a3: Plan Review (priority 7)",
# "a1: Draft Plan (priority 4)"
# ]
# a2 and a3 have priority 7, and a2 sorts before a3 alphabetically
tm.list_tasks(2, "Plan")
# [
# "a3: Plan Review (priority 7)",
# "a1: Draft Plan (priority 4)"
# ]
# Only names containing "Plan" qualify, with the best two returned
tm.list_tasks(10)
# Returns all 4 tasks in descending priority order
tm.list_tasks(2, "missing")
# [] (no task name contains "missing")
Enhance the system with users. A user has a quota that caps their number of active task assignments. Assignments include a TTL (Time-To-Live), so an assignment ends at start_time + ttl. One task may belong to several users, and each user may receive several tasks provided their quota is not exceeded.
def add_user(self, user_id: str, quota: int) -> bool:
"""
Register a user and set their task-assignment limit.
Args:
user_id: Unique identifier for the user.
quota: Greatest number of active task assignments the user
may have at one time.
Returns:
True if the user was added.
False if that user ID is already registered.
"""
pass
def assign_task(self, timestamp: int, user_id: str, task_id: str, ttl: int) -> bool:
"""
Give a user a task assignment that lasts for a TTL.
Args:
timestamp: Current time.
user_id: User receiving the task.
task_id: Task being assigned.
ttl: Duration of the assignment. It expires at timestamp + ttl.
Returns:
True if the assignment is created.
False if:
- The user is unknown.
- The task is unknown.
- The user's active-task quota is already full, considering
only assignments not expired at the current timestamp.
- This task is already actively assigned to that user and has
not expired.
Notes:
- Different users may be assigned the same task.
- Once an earlier assignment has expired, a user may receive the
same task again.
- Every invocation adds a separate assignment record with its own
start_time and TTL.
"""
pass
def list_user_tasks(self, timestamp: int, user_id: str) -> list:
"""
Return every active assignment belonging to one user.
Args:
timestamp: Current time.
user_id: User whose assignments should be returned.
Returns:
Strings formatted as "task_id: name (priority P)", sorted by
decreasing priority and then ascending task_id. Return an empty
list when the user does not exist or has no active assignments.
"""
pass
tm = TaskManager()
tm.create_task("q1", "Plan Sprint", 3)
tm.create_task("q2", "Run Checks", 6)
tm.create_task("q3", "Review Patch", 2)
tm.add_user("maya", 2) # True
tm.add_user("noah", 3) # True
tm.add_user("maya", 1) # False (duplicate user)
tm.assign_task(10, "maya", "q1", 8) # True (expires at 18)
tm.assign_task(11, "maya", "q2", 20) # True (expires at 31)
tm.assign_task(12, "maya", "q3", 15) # False (quota is 2, and both are active)
# A single task may be given to more than one user.
tm.assign_task(13, "noah", "q1", 9) # True (expires at 22)
# An active assignment cannot be repeated for the same user.
tm.assign_task(14, "maya", "q1", 10) # False (q1 remains active for maya)
tm.list_user_tasks(16, "maya")
# [
# "q2: Run Checks (priority 6)",
# "q1: Plan Sprint (priority 3)"
# ]
# q1 reaches its expiration time for maya at time 18.
tm.list_user_tasks(18, "maya")
# ["q2: Run Checks (priority 6)"]
# q1 is expired, so q2 is the sole active assignment
# An expired slot lets maya receive another task.
tm.assign_task(19, "maya", "q3", 8) # True
# q1 could be assigned again after expiring, but maya's quota is now full.
tm.assign_task(20, "maya", "q1", 5) # False (q2 and q3 are active, and quota is 2)