This article will be a bit shorter, but has some exercises to practice what we’ve covered so far as well as some other tricks for algorithms and similar outside of the language itself. The goal is to both grow language skills as well as growing our programming skills. Some exercises include extra information and Lua specific tricks.
Exercise 1
John has a store and wants a program to give him the total for a purchase. Use a while loop to make a basic calculator for John which gives him an output like below. Assume the tax rate is 8%.
ITEM: $10
TAX: $0.80
SUBTOTAL: $10.80
ITEM: $5
TAX: $0.40
SUBTOTAL: $16.20
ITEM: $TOTAL
TOTAL: $16.20
In order to make this look nice, we can use string.format( [format], [string] ) as found here. For our current example, we would use string.format( “%.2f”, [variable] ). Note that we also have a $ in front of TOTAL. Hard set this at this point to make this easier instead of messing with string formatting or making the user have to input this as well.
Variations:
Use repeat … until instead of while.
Lua has a way to check the type of scalar you are working with. The function type( [variable] ) returns the type. Lua includes a function tonumber( [variable] ) which converts a string or similar to a number if possible. When you use io.read() it will assume you are getting a string, but we can’t use io.read( “*n” ) or else it will fail when we get TOTAL or on any other error without explicit checks for nil.
Exercise 2
When we learned about arrays and tables here, we learned Lua allows you to treat arrays and tables as any other variable for reference. Let’s do something like we did for John before and write a program which allows us to do a little more than before. We want to write something which allows us to collect data about an item and its price and then we want to be able to use a command, CLEAR to clear the total and start over and EXIT to exit. We also want to be able to use DONE to finish our data entry. We want something like follows:
ITEM: shoes
PRICE: $10
ITEM: socks
PRICE: $1
ITEM: DONE
Input Items:
ITEM: shoes
PRICE: $10
TAX: $0.80
SUBTOTAL: $10.80
ITEM: shoes
PRICE: $10
TAX: $0.80
SUBTOTAL: $21.60
ITEM: TOTAL
TOTAL: $21.60
ITEM: shoes
PRICE: $10
TAX: $0.80
SUBTOTAL: $10.80
ITEM: CLEAR
ITEM: socks
PRICE: $1
TAX: $0.08
SUBTOTAL: $1.08
ITEM: TOTAL
TOTAL: $1.08
ITEM: EXIT
Make sure that EXIT works in either loop. In the second part, nothing should need to be entered except for the item name. Lua allows you to run exit() to exit a program.
Variations:
Lua has multiple string functions so that you can set a string to be uppercase or lowercase. Use string.lower( [string] ) and string.upper( [string] ) to make items not case sensitive.
Example Answers
Mouse over any given example to see the full code.
Example 1 Main:
#!/usr/bin/lua5.1
--set up our variables here
total = 0
item = ""
--main while loop
while item ~= "TOTAL" do
--setup our subtotal variable to track our cost
subtotal = 0
io.write( "ITEM: $" )
item = io.read()
--since TOTAL isn't a number, we'd get an error otherwise
if item ~= "TOTAL" then
tax = item * 0.08
subtotal = item + tax
print( "TAX: $" .. string.format( "%.2f", tax ) )
print( "SUBTOTAL: $" .. string.format( "%.2f", subtotal ) )
total = total + subtotal
end
print( "" ) --print a newline between each section
end
print( "TOTAL: $" .. string.format( "%.2f", total ) )
Example 1 Repeat … Until:
#!/usr/bin/lua5.1
--set up our variables here
total = 0
item = ""
--main while loop
repeat
--setup our subtotal variable to track our cost
subtotal = 0
io.write( "ITEM: $" )
item = io.read()
--since TOTAL isn't a number, we'd get an error otherwise
if item ~= "TOTAL" then
tax = item * 0.08
subtotal = item + tax
print( "TAX: $" .. string.format( "%.2f", tax ) )
print( "SUBTOTAL: $" .. string.format( "%.2f", subtotal ) )
total = total + subtotal
end
print( "" ) --print a newline between each section
until item == "TOTAL"
print( "TOTAL: $" .. string.format( "%.2f", total ) )
Example 1 Types:
#!/usr/bin/lua5.1
--set up our variables here
total = 0
item = ""
--main while loop
repeat
--setup our subtotal variable to track our cost
subtotal = 0
io.write( "ITEM: $" )
item = io.read()
--since TOTAL isn't a number, we'd get an error otherwise
if item ~= "TOTAL" and type( tonumber( item ) ) == "number" then
item = tonumber( item ) --do this to rule out any weirdness
tax = item * 0.08
subtotal = item + tax
print( "TAX: $" .. string.format( "%.2f", tax ) )
print( "SUBTOTAL: $" .. string.format( "%.2f", subtotal ) )
total = total + subtotal
else
print( "ERROR: You entered a bad value" )
end
print( "" ) --print a newline between each section
until item == "TOTAL"
print( "TOTAL: $" .. string.format( "%.2f", total ) )
Example 2 Main:
#!/usr/bin/lua5.1
--set up our variables here
total = 0
item = ""
items = {} --instantiate our table for all of our items
itemd = "" --itemd = item definition
repeat
--instantiate our loop variables
price = 0
tax = 0
sub = 0
io.write( "ITEM: " )
itemd = io.read()
if itemd == "EXIT" then exit() end
--we do this because otherwise, we'll run through the whole loop
if itemd ~= "DONE" then
if items[ itemd ] ~= nil then
print( "Warning: redefining: " .. itemd )
end
repeat
io.write( "PRICE: $" )
price = io.read()
until type( tonumber( price ) ) == "number"
tax = 0.08 * price
sub = price + tax
items[ itemd ] = { ["item"] = itemd, ["price"] = price, ["tax"] = tax, ["subtotal"] = sub }
end
print( "" )
until itemd == "DONE"
print( "Input Items:" )
--main while loop for pricing
repeat
io.write( "ITEM: " )
item = io.read()
--since TOTAL isn't a number, we'd get an error otherwise
if item ~= "TOTAL" and item ~= "CLEAR" and items[ item ] ~= nil then
price = items[ item ][ "price" ]
tax = items[ item ][ "tax" ]
subtotal = items[ item ][ "subtotal" ]
print( "TAX: $" .. string.format( "%.2f", tax ) )
print( "SUBTOTAL: $" .. string.format( "%.2f", subtotal ) )
total = total + subtotal
elseif item == "CLEAR" then
total = 0 --clear out our total again
print( "" )
elseif item == "TOTAL" then
print( "" )
print( "TOTAL: $" .. string.format( "%.2f", total ) )
total = 0 --clear out our total again
elseif item ~= "EXIT" then
print( "ERROR: You entered an incorrect item" )
end
print( "" ) --print a newline between each section
until item == "EXIT"
Example 2 No Cases:
#!/usr/bin/lua5.1
--set up our variables here
total = 0
item = ""
items = {} --instantiate our table for all of our items
itemd = "" --itemd = item definition
repeat
--instantiate our loop variables
price = 0
tax = 0
sub = 0
io.write( "ITEM: " )
itemd = io.read()
if itemd == "EXIT" then exit() end
--we do this because otherwise, we'll run through the whole loop
if itemd ~= "DONE" then
if items[ itemd ] ~= nil then
print( "Warning: redefining: " .. itemd )
end
repeat
io.write( "PRICE: $" )
price = io.read()
until type( tonumber( price ) ) == "number"
tax = 0.08 * price
sub = price + tax
items[ string.upper( itemd ) ] = { ["item"] = itemd, ["price"] = price, ["tax"] = tax, ["subtotal"] = sub } --note, string.lower would work too, but you'd have to change more code below!
end
print( "" )
until itemd == "DONE"
print( "Input Items:" )
--main while loop for pricing
repeat
io.write( "ITEM: " )
item = io.read()
item = string.upper( item ) --if we do this, we don't have to redefine our item
--since TOTAL isn't a number, we'd get an error otherwise
if item ~= "TOTAL" and item ~= "CLEAR" and items[ item ] ~= nil then
price = items[ item ][ "price" ]
tax = items[ item ][ "tax" ]
subtotal = items[ item ][ "subtotal" ]
print( "TAX: $" .. string.format( "%.2f", tax ) )
print( "SUBTOTAL: $" .. string.format( "%.2f", subtotal ) )
total = total + subtotal
elseif item == "CLEAR" then
total = 0 --clear out our total again
print( "" )
elseif item == "TOTAL" then
print( "" )
print( "TOTAL: $" .. string.format( "%.2f", total ) )
total = 0 --clear out our total again
elseif item ~= "EXIT" then
print( "ERROR: You entered an incorrect item" )
end
print( "" ) --print a newline between each section
until item == "EXIT"