Store several study tasks, print a label for each, and add up the unfinished work. Find the default completion state and follow how if and match choose the output.
Complete Values and Functions first. You will reuse function parameters, return values, and a counter declared with let mut.
Store and list the tasks
Save this code as data-control.tpz in your working folder.
record StudyTask {
title: string,
minutes: int,
done: bool = false,
}
function pace(task: StudyTask) -> string {
if task.done {
return "done"
}
match task.minutes {
case 1..15 => "quick"
case 16..30 => "focused"
case _ => "deep"
}
}
let tasks: Array<StudyTask> = [
StudyTask { title: "Run first program", minutes: 10, done: true },
StudyTask { title: "Build application", minutes: 25 },
]
let mut remaining = 0
for task in tasks {
if !task.done {
remaining = remaining + task.minutes
}
print("{task.title}: {pace(task)}")
}
print("remaining: {remaining} minutes")In that folder, check the file and run it.
topaz check data-control.tpz
topaz run data-control.tpzThe check succeeds with exit code 0. The program prints the tasks in array order, followed by the remaining time.
Run first program: done
Build application: focused
remaining: 25 minutesFind the fields and default value
StudyTask groups a title, a duration, and a completion state into a record. Each named part is a field. The declaration creates a distinct type named StudyTask.
The field done defaults to false. The second task omits it, so that task is unfinished. The first task supplies done: true and is complete.
Array<StudyTask> stores the two tasks in order. Each element has the type StudyTask. The for loop visits them in that order and uses task for the current element.
Follow if and match to the output
Inside the loop, if !task.done adds the duration of unfinished tasks to remaining. The ! reverses the boolean value. The first task adds nothing, and the second adds 25.
Inside pace, if task.done returns "done" for the first task. This return exits the function before match. The second task reaches match, which compares its duration with the cases in order.
| Duration of an unfinished task | Matching case | Returned label |
|---|---|---|
| 1 through 15 | case 1..15 | "quick" |
| 16 through 30 | case 16..30 | "focused" |
| Any other integer | case _ | "deep" |
The second task takes 25 minutes, so pace returns "focused". The selected case supplies the value of the match expression and the function result.
The _ pattern covers values that earlier cases did not match. It also accepts 0 and negative integers here. Keep this case so those inputs produce a result. In the next lesson, you will reject those durations before creating a task.
If your output differs, check each task's completion state and duration. A completed task prints done and adds no time, regardless of its duration.
Choose a collection
| What the program needs | Collection |
|---|---|
| Elements in order, with duplicates allowed | Array |
| Values found by a key | Map |
| Distinct elements without duplicates | Set |
Try this
Add StudyTask { title: "Review output", minutes: 5, done: true } as the third array element. Predict the new line and the remaining time, then check and run the file.
Answer
The new line is Review output: done. The integer remaining stays 25, so the final line is still remaining: 25 minutes. The added task is complete, so the loop skips the addition and pace returns before match.
Continue to the next lesson
You are ready when you can find the default false and explain why the two tasks print different labels. You should also be able to point to the if that excludes completed tasks from the total.
Continue to Failures and Resources to handle invalid durations. For reference, see Records & Nominal Data, Patterns & Control Flow, and Collections & Comprehensions.