Every program so far ran all of its statements, top to bottom, every time. Real programs respond to their input: they do one thing for some answers and something else for others. For that a program needs to ask a yes-or-no question and choose what to run.
Conditions are true or false
A comparison asks a question about two values. Its answer is one of two special values, true or false. These two values are called booleans.
print(3 < 5)
print(3 > 5)
print(4 == 4)
print(4 ~= 4)This prints true, false, true and false.
There are six comparison signs:
| Sign | Meaning |
|---|---|
== |
is equal to |
~= |
is not equal to |
< |
is less than |
> |
is greater than |
<= |
is less than or equal to |
>= |
is greater than or equal to |
Take care with the first one. A single = assigns a value to a variable. A double == asks whether two values are equal. The "not equal" sign is a tilde followed by an equals sign: ~=.
An expression that works out to true or false is called a condition.
if runs a block only when its condition is true
local temperature = 30
if temperature > 25 then
print("It is warm.")
print("Open a window.")
end
print("Done.")This prints It is warm., Open a window. and Done.. Change the 30 to 20 and run it again: now only Done. is printed.
An if statement has four parts: the word if, a condition, the word then, and, some lines later, the word end. The statements between then and end are called a block. They run when the condition is true, and are skipped when it is false. Either way, the program continues with whatever comes after end.
The statements in the block are moved to the right by four spaces. This is called indentation. Lua does not need it, but people do: it shows at a glance which statements belong to the if. Indent every block.
else gives the other path
Add else to say what should happen when the condition is false:
local age = 15
if age >= 18 then
print("You may vote.")
else
print("You may not vote yet.")
endThis prints You may not vote yet.. Exactly one of the two blocks runs, never both and never neither. There is still only one end, after the last block.
else. Both paths meet again after end.elseif chooses between several paths
When there are more than two possibilities, put elseif (one word) with a further condition between the if and the else:
local score = 72
if score >= 90 then
print("Grade A")
elseif score >= 70 then
print("Grade B")
elseif score >= 50 then
print("Grade C")
else
print("Not passed")
endThis prints Grade B.
Lua checks the conditions from the top and runs the block of the first one that is true. Then it jumps to the end; the remaining conditions are not even looked at. A score of 72 is also at least 50, but Grade C is not printed, because the chain stopped at the first match. The else block runs only when every condition was false.
else catches everything that is left.Because the first match wins, order matters. Put the most demanding condition first. If the chain above began with score >= 50, every passing score would be Grade C.
Write elseif as one word. else if with a space starts a second, separate if inside the else block, and that one needs an end of its own.
Decisions on input
Conditions become useful when the values come from the user. Remember to convert the answer to a number first.
io.write("How many items? ")
local items = tonumber(io.read("l"))
if items == 0 then
print("Your basket is empty.")
elseif items == 1 then
print("1 item in your basket.")
else
print(items .. " items in your basket.")
endWith the answer 3 the session is:
How many items? 3
3 items in your basket.Paste it into the Lua playground and try 0, 1 and 3 in the Standard input box.
Strings can be compared with == and ~= too: answer == "yes" is true only when the text is exactly yes, with the same capital and small letters.
Combining conditions
Three words build bigger conditions out of smaller ones:
a and bis true only when both are true.a or bis true when at least one is true.not aturns true into false and false into true.
local age = 10
local height = 130
print(age >= 8 and height >= 120)
print(age >= 12 or height >= 150)
print(not (age >= 8))This prints true, false and false. In the first line both parts are true. In the second, neither is. In the third, age >= 8 is true, and not reverses it.
In an if, a combined condition reads almost like English:
local day = "Sunday"
local raining = false
if day == "Sunday" and not raining then
print("Go for a walk.")
else
print("Stay in.")
endThis prints Go for a walk.
A number between two limits needs two comparisons joined by and: age >= 13 and age <= 19. Each side of and must be a complete comparison.
Three errors you will meet
One equals sign in a condition.
local age = 18
if age = 18 then
print("Happy birthday!")
endsolution.lua:2: 'then' expected near '='Lua read if age and was ready for the word then, but found a single =, which cannot appear in a condition. The fix is ==. Whenever a message says 'then' expected, look at the condition on that line: the usual causes are = in place of ==, or a forgotten then.
A missing end.
local temperature = 30
if temperature > 25 then
print("It is warm.")
print("Done.")solution.lua:5: 'end' expected (to close 'if' at line 2) near <eof><eof> stands for "end of file". Lua reached the end of the program while still waiting for an end. As with the missing bracket in the last lesson, the useful part is in the brackets: the if that was never closed is on line 2. Indentation makes this mistake easy to spot: the last line is not indented, so an end belongs above it.
Comparing text with a number. This program forgot tonumber:
local typed = "15" -- stands in for what the user typed
if typed < 18 then
print("Child ticket")
end/usr/bin/lua: solution.lua:2: attempt to compare string with number
stack traceback:
solution.lua:2: in main chunk
[C]: in ?Line 2 asks whether a piece of text is less than a number, and Lua refuses to guess what that means. Convert the input when you read it: local age = tonumber(io.read("l")).
A related trap gives no error at all: "15" == 15 is false, because a string and a number are never equal. Unconverted input makes an == test quietly fail.
What you can do now
You can compare values, write if / elseif / else chains that run exactly one block, combine conditions with and, or and not, and recognise the three commonest error messages. In the exercises you will trace which branch runs and then write a program that gives one of three answers.