Lua Exercises 1

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"