Learning Goals 3 min
By the end of this lesson you will be able to:
- Combine ask [] and wait with repeat until <> + add (answer) to [shopping v] to grow a list from typed input until the user says
done. - Read a list back item-by-item using the classic loop-through-list pattern: a counter variable, repeat (length of [shopping v]), and item (i) of [shopping v].
- Wire those two halves into a single working app — your first proper Scratch program with input, storage, and output.
Warm-Up — what's missing? 7 min
You've spent six lessons on lists — adding, deleting, replacing, asking for length, looping through items. Today you wire them together. But first, a prediction.
Hafiz writes this on the cat sprite to "make a shopping list app":
when flag clicked
ask [What do you want to buy?] and wait
add (answer) to [shopping v]
ask [What else?] and wait
add (answer) to [shopping v]
ask [What else?] and wait
add (answer) to [shopping v]
say (shopping) for (3) seconds
Click the flag in your head. Type roti, then susu, then telur. What's wrong with this app?
Reveal the answer
Two problems. First, the cat always asks exactly three times. If Mak wants to buy five things, too bad. If she only wants two, the cat awkwardly asks for a third. The number of items is hard-coded. Second, say (shopping) tries to read the whole list at once — and Scratch dumps it out as roti susu telur with no line breaks. That's not how a helper reads a list to you.
Today we fix both problems with two patterns you already know: repeat-until a sentinel, and loop-through-list with a counter. By the end of this lesson, the app will handle 1 item or 50 items, and read each one back clearly.
This is the whole point of Cluster B. A list isn't just a stack of boxes — it's a thing your program can grow, measure, and walk through. Today's lesson is the moment those pieces lock together.
New Concept — input, storage, output 15 min
Every useful program does the same three things in some order: it takes input from the user, it stores something, and it gives output back. Your shopping helper does all three. Let's look at the three patterns that make it work.
Pattern 1 — grow until a sentinel
A sentinel is a special value that means "stop". For our helper, the sentinel is the word done. The user types item, item, item, item — then types done, and the asking stops.
ask [What to add? Type 'done' to finish.] and wait
repeat until <(answer) = [done]>
add (answer) to [shopping v]
ask [What else? Type 'done' to finish.] and wait
end
Notice the shape: one ask outside the loop, then one ask at the end of every loop pass. The loop checks (answer) = [done] at the top — if the user typed done on the very first ask, the loop body never runs and the list stays empty. That's correct behaviour.
Pattern 2 — measure with length of
Before we read the list back, we need to know how many items we have. That's length of [shopping v] from the Variables palette (it appears once you've made a list). If the user added 4 items, length reports 4.
Pattern 3 — loop-through-list with a counter
This is the pattern from L03-12. We use a number variable — call it i for index — that starts at 1 and counts up. Each pass through the loop, we say item number i, then bump i up by one.
set [i v] to (1)
repeat (length of [shopping v])
say (item (i) of [shopping v]) for (1) seconds
change [i v] by (1)
end
i goes 1, 2, 3, … until every item has had its turn.Trace it for a list of [roti, susu, telur]:
- Pass 1 —
i = 1, cat saysroti, thenibecomes 2. - Pass 2 —
i = 2, cat sayssusu, thenibecomes 3. - Pass 3 —
i = 3, cat saystelur, thenibecomes 4. - Loop has run 3 times (length was 3). Stops.
iis left at 4 — that's fine, we don't use it again.
The shape of a real program
When you snap Pattern 1 and Pattern 3 under the same hat, you get a complete app. The first half talks to the user. The second half reads back. In between, the list quietly holds everything that was typed. That's a program.
Worked Example — build the helper end to end 15 min
Open Scratch. We'll build the whole helper in ten steps. Keep the default cat — it's the host of the app.
shopping watcher top-left with Add, 🔍 Find and ↕️ Sort buttons; the cat (the ✏️ sprite you script) runs all three. Add grows the list, Find runs linear search, Sort runs bubble sort over the prices.Step 1 — Make the list
Variables palette → Make a List → name it shopping → For all sprites → OK. A list watcher appears on the Stage. Drag it to the right side so it doesn't cover the cat.
Step 2 — Make the counter variable
Variables palette → Make a Variable → name it i → For this sprite only → OK. Uncheck its watcher box — we don't want i showing on Stage.
Step 3 — Reset on flag
Drop the hat when ⚑ clicked. Under it, add delete all of [shopping v] so each new run starts with an empty list.
Step 4 — First ask (outside the loop)
From Sensing: ask [What to add? Type 'done' to finish.] and wait. The cat will pause and show a text box.
Step 5 — The repeat-until-done loop
From Control: repeat until <>. Drop () = () from Operators into the diamond. Drag answer into the left slot, type done into the right slot. The diamond now reads <(answer) = [done]>.
Step 6 — Inside the loop, store then ask again
Inside the C: add (answer) to [shopping v], then a second ask [What else? Type 'done' to finish.] and wait. Order matters — store first, then ask for the next one.
Step 7 — Confirm with the user
Below the loop, add ask [Show your list? type yes] and wait, then if <> then with <(answer) = [yes]> in the diamond. Everything for the read-back goes inside this if.
Step 8 — Reset the counter
First block inside the if: set [i v] to (1). Without this, the second run of the app starts counting from wherever i ended last time.
Step 9 — Loop through and say each item
From Control: repeat (). Drop length of [shopping v] into the number slot. Inside the C: say (item (i) of [shopping v]) for (1) seconds, then change [i v] by (1).
Step 10 — Friendly sign-off
After the read-back loop (still inside the if), add say [Selamat membeli-belah!] for (2) seconds — Malay for "happy shopping". The app now greets, listens, stores, and reads back.
The full assembled stack
when flag clicked
delete all of [shopping v]
ask [What to add? Type 'done' to finish.] and wait
repeat until <(answer) = [done]>
add (answer) to [shopping v]
ask [What else? Type 'done' to finish.] and wait
end
ask [Show your list? type yes] and wait
if <(answer) = [yes]> then
set [i v] to (1)
repeat (length of [shopping v])
say (item (i) of [shopping v]) for (1) seconds
change [i v] by (1)
end
say [Selamat membeli-belah!] for (2) seconds
end
Click the flag. Type roti, susu, telur, pisang, then done. Type yes. Watch the cat read every item back. Run it again — type just done right away. The cat asks "Show your list?", you type no, the app ends cleanly. That handles every case.
Your second algorithm: bubble sort extra 10 min
The Helper can add and find. The last superpower Mak wants: "put my list in price order, most expensive first, so I budget the big things before the small ones." That job has a name too — sorting — and the friendliest sorting algorithm to learn is bubble sort.
Real-life hook: think of a row of children lining up by height, tallest on the left. The teacher walks the line and looks at each neighbouring pair. If the shorter child is on the left, the two swap places. She keeps sweeping the line again and again; each pass, the next tallest "bubbles" up to its spot — until one whole sweep happens with no swaps at all, which means the line is finally in order. A sports leaderboard sorts itself the same way: keep swapping any two neighbours that are out of order until nobody needs to move.
To swap two items in a Scratch list you can't just copy one over the other — you'd lose the first value. You need a temp (temporary) variable to hold one of them for a moment, like setting your teh tarik down to free both hands. Here is bubble sort in Scratch, sorting a scores list from highest to lowest (descending), with a tiny wait after each swap so you can watch the watcher reshuffle:
when flag clicked
set [swapped v] to (1)
repeat until <(swapped) = (0)>
set [swapped v] to (0)
set [i v] to (1)
repeat until <(i) = (length of [scores v])>
if <(item (i) of [scores v]) < (item ((i) + (1)) of [scores v])> then
set [temp v] to (item (i) of [scores v])
replace item (i) of [scores v] with (item ((i) + (1)) of [scores v])
replace item ((i) + (1)) of [scores v] with (temp)
set [swapped v] to (1)
wait (0.3) seconds
end
change [i v] by (1)
end
end
swapped remembers whether this pass moved anything; when a whole pass makes no swaps, the outer loop stops because the list is sorted. The wait (0.3) seconds lets you watch each swap on the Stage.Walk it slowly:
- set [swapped v] to (1) — pretend we just made a swap, so the outer loop runs at least once.
- repeat until <(swapped) = (0)> — keep doing passes until a whole pass makes no swaps.
- At the top of each pass: set [swapped v] to (0) (assume this pass won't swap) and set [i v] to (1) (start at the first pair).
- repeat until <(i) = (length of [scores v])> — walk every neighbouring pair: item
iand itemi+1. - if <(item (i) of [scores v]) < (item ((i) + (1)) of [scores v])> then — for descending order, if the left item is smaller than its right neighbour, they're in the wrong order, so swap.
- The swap: stash the left item in temp, copy the right item into the left slot, then copy temp into the right slot. Set swapped to 1 so we know this pass did something.
- change [i v] by (1) — move to the next pair.
For the Helper, swap a prices list instead of scores — same script, just the list name changes — so it sorts most-expensive-first. (If you'd rather sort the item names A→Z, the very same blocks work; just use () > () instead of () < () and Scratch compares the words alphabetically.) Keep the surrounding script minimal so the whole stack stays under the L3 20-block cap.
What you just built: your second algorithm. Together with linear search, you now know the two ideas — searching and sorting — that sit underneath almost every program ever written, from the contacts in your phone to the leaderboard in your favourite game.
Try It Yourself — three upgrades 12 min
Goal: Add an item counter to the sign-off. After the read-back, the cat should say You have N things to buy where N is the real number of items.
say (join [You have ] (join (length of [shopping v]) [ things to buy])) for (2) seconds
Think: The whole point of length of [shopping v] is that it gives you the real count without you having to track it yourself.
Goal: After the read-back, ask Remove an item? Type its name or 'no'. If the user types an item name that's in the list, delete it. (Hint: use delete (item # of (answer) in [shopping v]) of [shopping v] — yes, that's a real block combination.)
ask [Remove an item? Type its name or 'no'] and wait
if <not <(answer) = [no]>> then
delete (item # of (answer) in [shopping v]) of [shopping v]
say [Removed!] for (1) seconds
end
Think: item # of () in [shopping v] reports the position number of a value. If the user typed roti and roti is item 1, this reports 1 — and then we delete item 1. If roti isn't there, item # reports 0, and deleting item 0 does nothing.
Goal: Prevent duplicates. If the user tries to add an item already in the list (say they type roti twice), the cat should say Already on the list! and not add it again.
repeat until <(answer) = [done]>
if <(item # of (answer) in [shopping v]) > (0)> then
say [Already on the list!] for (1) seconds
else
add (answer) to [shopping v]
end
ask [What else? Type 'done' to finish.] and wait
end
Think: Item # of reports a position (1, 2, 3 …) when found, and 0 when not found. So > 0 means "this is already in there". This is your first real input-validation in Scratch.
Mini-Challenge — Aisyah's empty cat 5 min
"The cat says nothing"
Aisyah builds the helper. She types nasi lemak, teh tarik, done, yes. The cat asks "Show your list?" then… sits silent. Nothing is read back. Her stack:
when flag clicked
delete all of [shopping v]
ask [What to add?] and wait
repeat until <(answer) = [done]>
add (answer) to [shopping v]
ask [What else?] and wait
end
ask [Show your list?] and wait
if <(answer) = [yes]> then
repeat (length of [shopping v])
say (item (i) of [shopping v]) for (1) seconds
change [i v] by (1)
end
end
Reveal one valid solution
Aisyah forgot to reset the counter. The first time she ran the project, i climbed from 1 up to 3. The second run, i still starts at 3. When the loop tries item (3) of [shopping v], the list only has 2 items — so Scratch returns an empty string, and the cat says nothing visible.
The fix is one block:
if <(answer) = [yes]> then
set [i v] to (1)
repeat (length of [shopping v])
say (item (i) of [shopping v]) for (1) seconds
change [i v] by (1)
end
end
Resetting state at the top of a loop is one of those tiny disciplines that separates a program that works once from a program that works every time. Always reset what you'll change.
Recap 3 min
You built your first real Scratch program — not a sprite that wiggles, but a tool that does a job. The shopping helper pulls together every block from Cluster B: add to list, delete all of list, length of list, item () of list, plus the new combo of repeat until <> with a sentinel like done. The shape of every program is the same: input, storage, output. And you wired in two real algorithms — linear search to find, bubble sort to order. You've now shipped one.
- Sentinel value
- A special value that means "stop the loop". For our helper, the sentinel was
done. Common in real code too: programmers pick a value the user will never enter as real data, and use it as the off-switch. - Loop-through-list pattern
- The three-block combo that walks every item: set [i v] to (1) + repeat (length of [list v]) + change [i v] by (1) inside the C. Memorise this — you'll use it forever.
- Counter variable
- A number variable (we used
i) whose job is to count loop passes. It must be reset at the start of each new walk through the list, otherwise it carries leftover values from last time. - Capstone project
- A lesson where you don't learn new blocks — you wire everything from the cluster together into one working thing. Cluster B's capstone is the shopping helper. Cluster C's will be your first My Block.
- Input-storage-output
- The shape of every useful program. Input (ask, sensing), storage (list, variable), output (say, sound, looks). Once you see this shape, you'll see it in every app you ever use.
- Bubble sort
- A sorting algorithm that repeatedly compares each pair of neighbours and swaps any that are out of order, passing over the list until a whole pass makes no swaps. Needs a
tempvariable to swap two items without losing one. - Swap (with temp)
- Exchanging two values. You can't copy one straight over the other or you lose it — so you stash one in a temporary variable first, then move the second, then place the stashed one. The core move inside bubble sort.
Homework 2 min
Reskin the helper. Take the working shopping helper and turn it into a different kind of list app. Pick one:
- Wishlist for Hari Raya — change the prompts to
What do you want for Raya?and the sign-off toSelamat Hari Raya!. Same logic, different theme. - Homework tracker — change the prompts to
What homework do you have?and the read-back toDon't forget: .... Add a second listdone-homeworkand move items between them when the user types one as finished. - Quiz question bank — ask
Add a question?, store questions in one list and answers in a second list. The read-back asks each question and shows the answer after a wait.
Save as HW-L3-13-Helper.sb3. Hit the flag, walk through your app twice in a row to make sure the second run still works (that's how you catch a forgotten reset).
Bring back next class:
- The
.sb3file. - Your answer to: "In the worked example, count how many times the words
set [i v] toandchange [i v] byappear in your project. Why are these two blocks always together?"
Heads up for next class: SCR-L03-14 opens Cluster C — My Blocks. You'll meet the pink palette and the Make a Block button. It's a concept lesson — no code, just the big idea of why programmers bundle blocks into reusable named blocks. The hands-on building starts in L03-15.