The programs in the first lesson printed text that was fixed when you wrote them. Useful programs remember things and calculate with them. For that they need variables.
A variable is a name for a value
A value is a piece of data: a number, or some text. A variable is a name that refers to a value, so that you can use the value later by writing the name.
local price = 4
print(price)This prints 4. Read the first line as "make a new variable named price and give it the value 4". Giving a variable a value is called assignment, and the = sign does it. It does not mean "equals" as in mathematics; it means "now refers to".
The word local creates the variable. Write it once, the first time you use a new name. Without it Lua would still accept the line, but it would make a global variable, one shared with every part of the program, which any other part could change by accident; local keeps the variable to the place where you made it, so Lua programmers start every new variable with local.
Notice that print(price) has no quotation marks. With quotation marks, print("price") prints the word price. Without them, Lua looks up what the name refers to and prints that.
Three kinds of value
You will use three kinds of value in this unit:
- A whole number such as
4or-12is an integer. - A number with a decimal point such as
2.5is called a float (short for "floating-point number", the way computers store decimals). - Text between quotation marks such as
"notebook"is a string.
local quantity = 3
local price = 2.5
local item = "notebook"
print(quantity)
print(price)
print(item)This prints 3, 2.5 and notebook on three lines.
Arithmetic
Lua calculates with the usual signs. A piece of code that works out to a value, such as 2 + 3, is called an expression.
print(7 + 2)
print(7 - 2)
print(7 * 2)
print(7 / 2)
print(7 // 2)
print(7 % 2)This prints 9, 5, 14, 3.5, 3 and 1.
*multiplies./divides and always gives a float, even when the answer is whole:6 / 2is3.0.//divides and rounds down to a whole number: 7 divided by 2 is "3 and a bit", so7 // 2is3.%gives the remainder of that division: 7 is 3 twos with1left over.
Multiplication and division happen before addition and subtraction, as in school arithmetic. Round brackets change the order:
print(2 + 3 * 4)
print((2 + 3) * 4)This prints 14 and then 20.
When one of the numbers is a float, the answer is a float: 2.5 * 2 prints as 5.0, not 5.
Assignment works out the right-hand side first
An assignment has two steps. Lua first works out the value of everything to the right of the =. Then it makes the name on the left refer to that value.
That is why this line makes sense, even though it would be nonsense in mathematics:
local apples = 5
local eaten = 2
local left = apples - eaten
apples = apples + 10
print(left)
print(apples)This prints 3 and then 15. Line 4 has no local, because apples already exists: the line gives an existing variable a new value. Step through the diagram to see what each name refers to after each line.
apples on line 4 does not change left.A variable does not remember how its value was calculated. left was given the value 3; it is not a formula that follows apples around.
Choosing names
A name can contain letters, digits and the underscore _, and must not start with a digit. Capital letters count: total and Total are different names. Choose names that say what the value means: price and quantity are better than p and q. When a name needs two words, join them with an underscore, as in unit_price.
Joining text and values
Two dots, .., join two pieces of text into one string. Programmers call this concatenation.
local item = "notebook"
local quantity = 3
print("Item: " .. item)
print("Quantity: " .. quantity)This prints:
Item: notebook
Quantity: 3The space after the colon is inside the quotation marks. .. adds nothing of its own, so any space you want must be in one of the strings. When one side of .. is a number, Lua turns the number into text for you. Put a space on each side of the dots, especially next to a number: 3..4 confuses Lua, 3 .. 4 does not.
print with the finished string.You can join as many pieces as you like in one expression: "You bought " .. quantity .. " of them."
Money needs two decimal places
A float is printed with as many digits as it needs, so 2.5 * 3 prints as 7.5. A price should read 7.50. The function string.format builds a string from a pattern and a value:
local total = 2.5 * 3
print(total)
print(string.format("%.2f", total))
print("Total: " .. string.format("%.2f", total))This prints 7.5, then 7.50, then Total: 7.50. The pattern "%.2f" means "a number with exactly two digits after the decimal point". Change the 2 to a 1 and run it again to see one digit.
Two errors you will meet
A misspelt variable name. The variable is total, but line 2 says totl:
local total = 12
print("Total: " .. totl)/usr/bin/lua: solution.lua:2: attempt to concatenate a nil value (global 'totl')
stack traceback:
solution.lua:2: in main chunk
[C]: in ?Read the first line: line 2, and the name in brackets is totl. (The message calls it global because no local line ever created it.) Remember that nil means "nothing". Lua does not know any variable named totl, so the name refers to nothing, and nothing cannot be joined to a string. "Concatenate" is the name for what .. does. Whenever a message says nil value and names a variable, check the spelling of that name first.
Using + to join text. + is only for numbers:
local total = 12
print("Total: " + total)/usr/bin/lua: solution.lua:2: attempt to add a 'string' with a 'number'
stack traceback:
[C]: in metamethod 'add'
solution.lua:2: in main chunk
[C]: in ?Again the first line is the one to read: on line 2 you tried to add a string and a number. To join text, use ... The traceback is one line longer this time; the line of your program is still the one that starts with solution.lua:2.
What you can do now
You can create variables with local, store integers, floats and strings in them, calculate with + - * / // %, and build lines of output with .. and string.format. In the exercises you will trace what small programs print and then write a program that calculates and prints a receipt.
Next: read what the user types, so that a program can work with values it did not know in advance.