Learn Topaz

Data and Control

Store study tasks in records and an array, classify them with if and match, and add their remaining minutes.

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.

TOPAZ
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.

BASH
topaz check data-control.tpz
topaz run data-control.tpz

The check succeeds with exit code 0. The program prints the tasks in array order, followed by the remaining time.

Output
Run first program: done
Build application: focused
remaining: 25 minutes

Find 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 taskMatching caseReturned label
1 through 15case 1..15"quick"
16 through 30case 16..30"focused"
Any other integercase _"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 needsCollection
Elements in order, with duplicates allowedArray
Values found by a keyMap
Distinct elements without duplicatesSet

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.