Lists
A variable holds one number. A list holds many, in order, under one name — so a robot can remember every reading it took rather than only the most recent.
A corridor of lockers
If a variable is a piece of paper with one number on it, a list is a row of lockers. Each locker has a number on the door, and each one holds something of its own. They all share a name — snacks, colours — and you tell them apart by the number, not the name.
The doors matter. You cannot see what is in the whole row at a glance: to find out what is in locker 3, you have to open locker 3. And if you want to change what is in there, you open it, take out what is inside, and put something else in. Try it — click a door.
Three lockers are in use. You cannot see inside any of them until you open one — click a door.
Every list block is one of those physical actions, and the block for whatever you just did appears underneath the lockers:
| Block | The locker version |
|---|---|
add [banana] to [snacks v] | Put a banana in the next free locker. Always the end of the row. |
(item (3) of [snacks v]) | Open locker 3 and tell me what is inside. One locker, one look. |
replace item (3) of [snacks v] with [candy] | Open 3, take out what is there, put candy in. Nothing else moves. |
delete (3) of [snacks v] | Empty locker 3 and close up the gap — everything after it shuffles down one. What was in 4 is now in 3. |
(length of [snacks v]) | How many lockers are in use. |
delete all of [snacks v] | Empty the whole row. This belongs at the top of a program. |
Deleting is the one that catches people. A locker does not stay empty — the row closes up. Delete item 2 of a five-item list and you have a four-item list, with everything after position 2 now one number lower than it was. Any position you wrote down before the delete is wrong afterwards.
What a robot puts in them
Lists are not only for numbers. Anything a block can report can go in one:
- Colours from the Colour Sensor. Drive along a line of coloured cards adding each reading, and at the end the robot has the whole sequence — not just the last card it went over.
- Positions in degrees. A list of angles is a list of places an arm should go: 0, 90, 180, 270. Walking the list drives the arm through the positions in order, and changing where it stops means editing a number rather than rewriting the program.
- Words. apple, banana, candy — a vending machine holds its stock in one list and the matching prices or positions in another, so item 2 of one lines up with item 2 of the other.
Blocks reference
| Block | What it does |
|---|---|
add [thing] to [List v] | Puts a new value on the end. |
(item (1) of [List v]) | Reads the value at a position. Positions start at 1. |
(length of [List v]) | Reports how many values are stored. |
delete all of [List v] | Empties it. This belongs at the top of the program, for the same reason a variable is set to zero there. |
Collecting readings
The natural shape is a loop that takes a reading and adds it. Watch the same four readings go into a variable and into a list.
into a variable
into a list
Watch the variable box, not the list. Every reading it shows is correct; it is the ones it has already forgotten that matter.
Notice that the variable is never wrong. Every number it shows is a real reading, correctly taken, moments ago. It simply has room for one, so each new reading pushes the last one out — and by the fourth stop three readings have quietly ceased to exist.
Afterwards the list can be walked to find the largest, the smallest, or the average — none of which is possible if you only ever kept the latest value.
Positions count from 1, not 0. A loop that starts its counter at 0 reads a position that does not exist and misses the first entry.
Reading the whole list out
Storing readings is only half of it. To use a list you walk it, and that needs one more idea: a variable that holds a position rather than a value. Call it i. Set it to 1, read item i, then change i by 1 — and the next pass round the loop looks at the next locker.
Two things make this work without anybody counting. The loop repeats length of colours, so it runs once per item however many there are; and i doubles as the screen line, so each item lands on its own row.
when program starts :: events hat delete all of [colours v] add [red] to [colours v] add [blue] to [colours v] add [green] to [colours v] add [yellow] to [colours v] clear display :: display set [i v] to (1) repeat (length of [colours v]) write (item (i) of [colours v]) at line (i) :: display change [i v] by (1) end
Watch i rather than the blocks. It is the only thing that changes between one pass and the next, and it is what makes each pass look at a different locker.
Nowhere does that program mention the number four. Add a fifth colour and it writes five lines, unchanged — which is the whole reason to ask a list its length rather than typing a number you will have to remember to update.
Going further: sorting, and finding the biggest
Once a robot can walk a list it can do real work on one. Both of these are the same trick — go along comparing two items at a time — and they differ only in what they do about it. Sorting swaps the pair; finding the biggest just remembers the winner.
when program starts :: events hat
set [i v] to (1)
repeat ((length of [nums v]) - (1))
set [j v] to (1)
repeat ((length of [nums v]) - (i))
if <(item (j) of [nums v]) > (item ((j) + (1)) of [nums v])> then
set [temp v] to (item (j) of [nums v])
replace item (j) of [nums v] with (item ((j) + (1)) of [nums v])
replace item ((j) + (1)) of [nums v] with (temp)
end
change [j v] by (1)
end
change [i v] by (1)
endOnly ever two numbers are being compared at a time. A sort looks complicated because it repeats, not because any one step is hard.
A bubble sort looks hard because it is a loop inside a loop, but no single step is: compare two neighbours, swap them if they are the wrong way round, move along one. Each full pass floats the biggest remaining number to the end — which is where the name comes from — so after as many passes as there are items, the list is in order.
Finding the biggest needs no swapping at all. Assume the first item is the winner, walk the rest, and whenever you meet something bigger, remember that instead. One pass, one variable. Swap the > for a < and the same program finds the smallest — which is how a line-following robot works out its black and its white before choosing a threshold between them.
Why it matters
This is data collection — a robot driving a course while recording distances, then reporting what it found. It is the difference between a machine that reacts and one that measures.
More data tutorials
- Variables — Give the robot a number it can remember and change as it works.
- Broadcasting a message — Let one stack of blocks tell another stack to start.
- My Blocks — Name a group of blocks so it can be reused instead of copied.
- Random numbers — Make the robot behave unpredictably on purpose.