Back

Activity 1.16: Counting Loops

divider

Activity 1.16

Counting Loops

Key Concepts

A Loop That Counts For You

Using the Counter

Drawing N Things

What You Are Building

Eight circles in a row across a black window, shading from blue on the left to orange on the right

Eight circles from one circle command.

Last Session, the Long Way

local count = 1
while count <= 8 do
print(count)
count = count + 1
end

Last Session, the Long Way

local count = 1
while count <= 8 do
print(count)
count = count + 1
end

Start it, check it, change it. Three lines of bookkeeping for one line of work.

Today, the Short Way

for i = 1, 8 do
print(i)
end

Today, the Short Way

for i = 1, 8 do
print(i)
end
Terminal window
1
2
3
4
5
6
7
8

All three parts are on the first line. You cannot forget the one that changes.

Reading the First Line

for i = 1, 8 do
i
A variable the loop makes for you. You pick the name.
1
What it starts at.
8
What it counts up to, and including.

Eight passes, and i is 8 on the last one. Not 7.

A Third Number Changes the Step

for i = 1, 10, 3 do
print(i)
end

A Third Number Changes the Step

for i = 1, 10, 3 do
print(i)
end
Terminal window
1
4
7
10

It stopped at 10 because 13 would be past the end.

And a Negative Step Goes Backwards

for i = 5, 1, -1 do
print(i)
end

And a Negative Step Goes Backwards

for i = 5, 1, -1 do
print(i)
end
Terminal window
5
4
3
2
1

Which is last session's countdown, in one line.

The Counter Is the Useful Part

i is not just bookkeeping. It is a different number on every pass, and you can put it anywhere a number goes.

Which is how one circle line draws eight circles in eight places.

i Only Exists Inside

for i = 1, 3 do
print("inside " .. i)
end
print("after: " .. tostring(i))

i Only Exists Inside

for i = 1, 3 do
print("inside " .. i)
end
print("after: " .. tostring(i))
Terminal window
inside 1
inside 2
inside 3
after: nil

The loop made it, used it, and threw it away. Outside, it is nil.

Today's Objectives

  • Write a counting loop
  • Use the counter inside the loop
  • Change the start, the end, and the step
  • Draw N shapes from one drawing command

Key Terms

for
A loop that counts, with all three parts on one line.
Loop counter
The variable the loop makes and changes for you.
Step
How much the counter changes each pass. One unless you say otherwise.
Scope
Where a name exists. The counter exists only inside its loop.

'F' → Fullscreen

divider

Build

Task 1: Count in the Terminal

Copy template-console to 1-16-count. Predict the output of each of these before running it, and write both your prediction and the result:

main.lua
for i = 1, 5 do
print(i)
end
for i = 3, 7 do
print(i)
end
for i = 1, 10, 2 do
print(i)
end
for i = 10, 1, -2 do
print(i)
end

The third and fourth are the ones people get wrong. Count how many lines each produces before you run it.

Task 2: Use the Counter

Add these two, and work out what they do first:

main.lua
for i = 1, 10 do
print(i .. " times 7 is " .. i * 7)
end
for i = 1, 5 do
print(i .. " squared is " .. i * i)
end

A times table in three lines. Change the 7 and you have a different one.

Task 3: Eight Circles, One Command

Copy template-game to 1-16-row:

main.lua
local count = 8
local gap = 800 / (count + 1)
function love.draw()
for i = 1, count do
love.graphics.circle("fill", i * gap, 300, 34)
end
end

Run it, then change count to 3, then to 20. The circles space themselves out, because gap is worked out from count rather than typed in.

Why count + 1? With 8 circles there are 9 gaps — one before the first and one after the last. Try 800 / count instead and see where the last circle ends up.

Task 4: Make the Counter Visible

Use i for the color as well as the position:

main.lua
for i = 1, count do
love.graphics.setColor(i / count, 0.4, 1 - i / count)
love.graphics.circle("fill", i * gap, 300, 34)
end
Eight circles shading smoothly from blue on the left to orange on the right

Every circle is drawn by the same line of code, and no two look the same. Write down what i / count is on the first pass and on the last.

Task 5: Your Own Pattern

Change the row into something of your own. Pick at least two:

  • Make the circles grow as they go across, using i for the radius
  • Make them into a diagonal line instead of a row
  • Draw squares, and rotate the colors the other way
  • Use a negative step so the loop draws right to left, and explain why the picture is identical

Challenge (Optional): Break It on Purpose

Move the drawing line outside the loop:

main.lua
for i = 1, count do
end
love.graphics.circle("fill", i * gap, 300, 34)

The window turns blue. Copy the message, then explain it using what the slides said about where i exists.

Challenge (Optional): A Circle of Circles

Arrange the circles in a ring instead of a row. You need math.cos and math.sin, and the angle for circle i out of count is i / count * 2 * math.pi.

This is a real use of trigonometry and you are not expected to derive it. Multiply the cosine by a radius, add 400, and see what happens.

divider

Same Idea, Exam Notation

The exam has a counting loop, and it does not give you a counter. This is the widest gap between Lua and the exam sheet in the whole quarter.

Lua
for i = 1, 8 do
print(i)
end
Exam Notation
i ← 1
REPEAT 8 TIMES
{
DISPLAY(i)
i ← i + 1
}

REPEAT n TIMES has no variable in it

REPEAT 8 TIMES runs a block eight times and tells you nothing about which pass you are on. If you need to know, you make your own counter, start it yourself, and add to it yourself — exactly the bookkeeping Lua's for removed.

Lua forREPEAT n TIMES
Runs a fixed number of timesYesYes
Gives you a counterYesNo
Can start somewhere other than 1YesOnly by hand
Can step by something other than 1YesOnly by hand
There is no C-style for loop on the exam sheet at all. Two loops, and that is the whole list: REPEAT n TIMES and REPEAT UNTIL(condition).

On a trace question, the counter is usually the thing being asked about — so when you see REPEAT n TIMES, look for the variable somebody had to maintain by hand, and watch where it changes.

divider

Checkpoint

  • All four counting loops in task 1 have a prediction and a result written down
  • 1-16-row draws its circles from one circle line inside a loop
  • Changing count alone changes how many there are and respaces them
  • Two of the task 5 variations are done
divider

Reflection

Answer the following questions before submitting your work.

  1. Last session's while loop needed three separate parts and this session's for puts all three on one line. Explain which kind of bug that makes impossible, and give an example of something while can still do that for cannot.
  2. Your eight circles were drawn by one line of code. Explain how one line put eight different shapes in eight different places.
  3. The exam's REPEAT n TIMES gives you no counter. Describe what you would have to add to it to draw your row of circles, and say how many extra lines that is.
divider

Submit

Submit the required files to the appropriate dropbox.

Activity Complete