Menu
Coddy logo textTech

Putting It All Together

Part of the Introduction To Luau section of Coddy's Lua journey. Lesson 50 of 73.

challenge icon

Challenge

Medium

Your editor already contains the complete toolkit: the Task type, the tasks array (three starter tasks), addTask, completeTask, filterTasks and printSummary.

Write a command loop that keeps reading a line with io.read() and handles these commands:

  • add — read one more line as the title, call addTask, and print exactly: Added task {id}: {title} (using the returned task's fields)
  • done — read one more line, convert it with tonumber(...) or 0, call completeTask; print Task {id} completed if it returned true, otherwise No task with id {id}
  • list — for every task, print [x] {title} if it's done, otherwise [ ] {title} (note the space)
  • pending — print the title of every unfinished task, using filterTasks
  • summary — call printSummary(tasks)
  • quit — stop the loop (also stop if io.read() returns nil)

Try it yourself

-- The shape every task in the manager must follow
type Task = {
    id: number,
    title: string,
    done: boolean,
}

-- The task list: a typed array of Task shapes
local tasks: {Task} = {
    {id = 1, title = "Learn Luau types", done = false},
    {id = 2, title = "Build a task manager", done = false},
    {id = 3, title = "Write tests", done = true},
}

-- Build a typed task with the next free id and insert it
local function addTask(list: {Task}, title: string): Task
    local newTask: Task = {
        id = #list + 1,
        title = title,
        done = false,
    }
    table.insert(list, newTask)
    return newTask
end

-- Mark the task with the given id as done; report success
local function completeTask(list: {Task}, id: number): boolean
    for _, t in ipairs(list) do
        if t.id == id then
            t.done = true
            return true
        end
    end
    return false
end

-- Collect the tasks whose done flag matches into a new {Task}
local function filterTasks(list: {Task}, done: boolean): {Task}
    local result: {Task} = {}
    for _, t in ipairs(list) do
        if t.done == done then
            table.insert(result, t)
        end
    end
    return result
end

-- Print a one-line progress summary
local function printSummary(list: {Task}): ()
    local total = #list
    local doneCount = 0
    for _, t in ipairs(list) do
        if t.done then
            doneCount = doneCount + 1
        end
    end
    print(`{doneCount}/{total} tasks done`)
end

-- Watch the summary change as the list evolves
printSummary(tasks)
completeTask(tasks, 2)
printSummary(tasks)
addTask(tasks, "Take a break")
printSummary(tasks)

All lessons in Introduction To Luau

Practice on your own: Online Lua compiler