CodeBlanks Logo Icon CodeBlanks

Putting it together

Build a working CLI app with a menu loop.

Putting it together: a full CLI scenario

All pieces are now ready: the Task data class, TodoList with addTask, listTasks and completeTask. In this final lesson you will combine them into a single scenario.

val list = TodoList()
list.addTask("Shopping")
list.addTask("Homework")
list.addTask("Sport")
list.completeTask("Homework")
list.listTasks()

In a real CLI these calls would happen inside a menu loop driven by user commands. Here we keep the scenario fixed so the output is deterministic.

The menu loop concept

In a real CLI a while (true) loop reads a command from the user and a when dispatches to the right method. In this lesson the scenario is fixed, so there is no loop; but the logic is the same.

while (true) {
    val cmd = readln()
    when (cmd.substringBefore(':')) {
        "add" -> list.addTask(cmd.substringAfter(':'))
        "done" -> list.completeTask(cmd.substringAfter(':'))
        "list" -> list.listTasks()
        else -> return
    }
}

This structure lets the user decide the order of commands. In our scenario the order is fixed in the code; this gives a deterministic test output.

Practice Run the full CLI scenario

In main create a TodoList. Add three tasks in order: list.addTask("Shopping"), list.addTask("Homework"), list.addTask("Sport"). Then complete "Homework" with list.completeTask("Homework") and print all tasks with list.listTasks().

Starter code

Main.kt
fun main() {
    val list = TodoList()
    // Add 3 tasks, complete one of them, print with listTasks
}

// The Task and TodoList classes stay as defined in the previous lesson.

Sample solution

Main.kt
fun main() {
    val list = TodoList()
    list.addTask("Shopping")
    list.addTask("Homework")
    list.addTask("Sport")
    list.completeTask("Homework")
    list.listTasks()
}

data class Task(val title: String, val done: Boolean = false) {
    fun format() = if (done) "[x] $title" else "[ ] $title"
}

class TodoList {
    val tasks = mutableListOf<Task>()
    fun addTask(title: String) { tasks.add(Task(title)) }
    fun listTasks() { tasks.forEach { println(it.format()) } }
    fun completeTask(title: String) {
        val i = tasks.indexOfFirst { it.title == title }
        if (i >= 0) { tasks[i] = tasks[i].copy(done = true) }
    }
}

Expected output

[ ] Shopping
[x] Homework
[ ] Sport

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which sequence adds, completes and lists?

  • completeTask, addTask
  • addTask, listTasks
  • addTask, addTask, addTask, completeTask, listTasks Correct answer
  • listTasks, listTasks, listTasks

Explanation: Three adds, one complete and one list give the full scenario.

2 Match method to role

Term Meaning
addTask Add a task
completeTask Complete a task
listTasks Print all tasks
copy(done = true) New copy, done true

3 Fill in the blank: menu loop

Question
for (cmd ____ menu) list.handle(cmd)
Answer
for (cmd in menu) list.handle(cmd)

Explanation: for (cmd in menu) walks the command sequence.

All lessons in Beginner