Learning Lua Step-By-Step (Part 2)

This entry is part 3 of 24 in the series Learning Lua Step-By-Step

Post Stastics

  • This post has 2915 words.
  • Estimated read time is 13.88 minute(s).

Variables

What are variables

Variables are named containers that store data in a program. They allow you to store and manipulate values that can change throughout the execution of your Lua code.

Naming Variables

Lua variable names must start with a letter or underscore, and can contain letters, digits, and underscores. It’s common to use camelCase or snake_case for variables with multiple words.

-- Valid variable names in Lua
name = "John"
age = 7
_index = 12  -- Variables may start with an underscore
full_name = "Tom Brady" -- Variables may contain an underscore
Janitor = "Mike Scruggs"  -- Variables may contain upper and lower alpha characters
Team_12 = "Golden Girls"  -- Variables may contain underscores and numbers

-- Invalue variable names
1_firstName = "Tom Jones"   -- Starts with a number
#_column1 = "Sub Totals"    -- Starts with invalid character

When to use variables

Variables are essential for storing and working with data in your Lua programs. They allow you to create dynamic, reusable code that can adapt to different situations and inputs.

Assigning values to variables

You can assign values to variables using the = operator. For example:

local myVariable = 42
myVariable = "Hello, world!"

Conditional Statements

Conditional statements allow your Lua program to make decisions and take different actions based on certain conditions. The most common conditional statement is the if-then-else statement.

if condition then
  -- code to be executed if condition is true
else
  -- code to be executed if condition is false
end

In addition to the if-then-else statement, Lua also supports the following conditional statements:

Ternary Operator

The ternary operator is a shorthand way of writing a simple if-then-else statement. The syntax is:

condition and value_if_true or value_if_false

For example:

local age = 18
local canVote = age >= 18 and "Yes" or "No"
-- canVote will be "Yes"

Elseif:

The elseif statement allows you to chain multiple conditions together, executing different code blocks based on the evaluation of each condition.

if condition1 then
  -- code block 1
elseif condition2 then
  -- code block 2
elseif condition3 then
  -- code block 3
else
  -- code block 4
end

Switch/Case:

Lua doesn’t have a built-in switch or case statement like some other programming languages. However, you can achieve a similar functionality using a combination of if-elseif-else statements and the equality operator (==).

local day = 3
if day == 1 then
  print("Monday")
elseif day == 2 then
  print("Tuesday")
elseif day == 3 then
  print("Wednesday")
else
  print("Invalid day")
end

Logical Operators:

Lua’s logical operators (and, or, and not) can be used to create more complex conditional statements.

local isStudent = true
local isAdult = age >= 18
if isStudent and isAdult then
  print("You are an adult student.")
elseif isStudent or isAdult then
  print("You are either a student or an adult.")
else
  print("You are neither a student nor an adult.")
end

These conditional statements, along with the if-then-else statement, provide you with the necessary tools to make decisions and control the flow of your Lua programs.

Scopes

What is Scope

Scope refers to the region of your program where a variable is accessible. Lua has different scopes, including global, local, file, and block scopes.

Global

Global variables can be accessed from anywhere in your Lua program. However, it’s generally recommended to use local variables whenever possible to avoid unintended side effects.

Local

Local variables are only accessible within the block of code (such as a function or a doend block) where they are defined.

File

Variables declared at the top level of a Lua file have file scope, meaning they can be accessed throughout the entire file.

Block

Variables declared within a block (such as an if statement or a for loop) have block scope and are only accessible within that block.

Functions

In Lua, a function is a reusable block of code that performs a specific task. Functions allow you to encapsulate and organize your code, making it more modular, maintainable, and easier to test. Functions can take zero or more arguments, which are values passed into the function, and can optionally return one or more values.

Here’s an example of a simple function in Lua that calculates the area of a rectangle:

function calculateArea(length, width)
  local area = length * width
  return area
end

-- Usage
local rectangleLength = 5
local rectangleWidth = 3
local areaOfRectangle = calculateArea(rectangleLength, rectangleWidth)
print("The area of the rectangle is: " .. areaOfRectangle)

In this example, the calculateArea function takes two arguments, length and width, and calculates the area by multiplying them together. The function then uses the return keyword to send the calculated area back to the calling code. The function can be called from anywhere in your Lua program, and you can pass different values for the length and width to get the corresponding area.

Functions in Lua can also be anonymous (also known as lambda functions or closures), which means they don’t have a named identifier and can be assigned to variables or passed as arguments to other functions. This allows for the creation of more flexible and reusable code.

Passing arguments to a function

You can pass arguments to a Lua function by listing them within the function’s parentheses. These arguments are then available as local variables within the function.

function add(a, b)
  return a + b
end

Returning values from a function

Lua functions can return one or more values using the return keyword.

function calculateArea(length, width)
  local area = length * width
  return area
end

A Simple Calculator

Let’s create a simple calculator program in Lua that can perform basic arithmetic operations.

print("Welcome to the Lua Calculator!")

local num1 = tonumber(input("Enter the first number: "))
local num2 = tonumber(input("Enter the second number: "))

local sum = num1 + num2
local difference = num1 - num2
local product = num1 * num2
local quotient = num1 / num2

print("The sum is: " .. sum)
print("The difference is: " .. difference)
print("The product is: " .. product)
print("The quotient is: " .. quotient)

Math Operators

Order of Operations

Lua follows the standard order of operations (PEMDAS: Parentheses, Exponents, Multiplication/Division, Addition/Subtraction).

Addition/Subtraction

The + operator is used for addition, and the - operator is used for subtraction.

local x = 10
local y = 3
local sum = x + y        -- sum = 13
local difference = x - y -- difference = 7

Multiplication/Division

The * operator is used for multiplication and the / operator is used for division.

local x = 10
local y = 3
local product = x * y    -- product = 30
local quotient = x / y   -- quotient = 3.3333333333333

Modulus (Remainder)

The % operator, also known as the modulus operator, returns the remainder of a division operation.

What is modulus

The modulus operator is useful for a variety of tasks, such as:

Printing all Even number

You can use the modulus operator to check if a number is even by checking if it’s divisible by 2 with a remainder of 0.

Printing all odd number

Similarly, you can check if a number is odd by checking if it’s not divisible by 2 with a remainder of 0.

Fizz Buzz

The classic “FizzBuzz” problem can be solved using the modulus operator to check if a number is divisible by 3 and/or 5.

24 Hour time to AM PM Example

The modulus operator can be used to convert 24-hour time to 12-hour AM/PM format.

Loops

Loops in Lua

Loops are an essential control structure in Lua that allow you to repeatedly execute a block of code. Lua provides several types of loops to cater to different use cases.

for Loop

The for loop is one of the most common loop structures in Lua. It allows you to iterate over a sequence of values, such as numbers or elements in a table.

The basic syntax for a for loop is:

for i = start_value, end_value, step do
  -- code block
end

Here’s an example that prints the numbers from 1 to 5:

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

You can also use a for loop to iterate over the elements of a table:

local fruits = {"apple", "banana", "cherry"}
for i = 1, #fruits do
  print(fruits[i])
end

while Loop

The while loop repeatedly executes a block of code as long as a given condition is true.

while condition do
  -- code block
end

Here’s an example that prints the numbers from 1 to 5:

local i = 1
while i <= 5 do
  print(i)
  i = i + 1
end

repeat-until Loop

The repeat-until loop is similar to the while loop, but the condition is checked at the end of the loop instead of the beginning.

repeat
  -- code block
until condition

Here’s an example that prints the numbers from 1 to 5:

local i = 1
repeat
  print(i)
  i = i + 1
until i > 5

break and continue

Lua also provides the break and continue statements to control the flow of a loop.

  • break terminates the current loop and transfers the control to the next statement outside the loop.
  • continue skips the current iteration of the loop and moves on to the next iteration.

Here’s an example that demonstrates the use of break and continue:

for i = 1, 10 do
  if i % 2 == 0 then
    -- Skip even numbers
    goto continue
  end
  if i == 7 then
    -- Terminate the loop when i is 7
    break
  end
  print(i)
  ::continue::
end

This will output:

1
3
5

Loops in Lua provide you with the flexibility to repeatedly execute code, making it easier to solve complex problems and automate repetitive tasks.

Using Libraries

In Lua, libraries are typically organized as modules, and you don’t need to explicitly “import” them like in some other programming languages. Instead, you access the functionality provided by a Lua library through the module’s global table.

Here’s how you can use Lua libraries:

  1. Standard Library:
    The standard Lua library is automatically available in every Lua program. You can access its functions and variables directly, without any additional setup. For example, you can use the print() function from the standard library like this:
   print("Hello, World!")
  1. Loaded Modules:
    Lua provides a way to load and use additional modules (libraries) through the require() function. When you call require("module_name"), Lua will try to find the module, load it, and return the module’s table, which you can then use to access the module’s functions and variables.
   local math_lib = require("math")
   local pi = math_lib.pi
   local sqrt_result = math_lib.sqrt(25)

In this example, the math module is loaded, and its functions and variables are accessed through the math_lib table.

  1. Global Modules:
    Some Lua libraries are designed to be loaded globally, meaning their functions and variables are available directly in the global namespace, without the need to store them in a table. These are typically low-level, commonly used libraries.
   local random_number = math.random(1, 100)

In this case, the math library is loaded globally, and you can access its functions (like math.random()) directly.

It’s important to note that while the standard Lua library is always available, additional libraries need to be loaded using the require() function or by being designed as global modules. This allows Lua to keep the core language small and lightweight while providing a way to extend its functionality as needed.

Getting Random numbers

The math library in Lua provides the math.random() function, which can be used to generate random numbers.

print(math.random()  -- Returns a random value between 0 and 1.

Seeding the random number generator

The random number generator will return the same sequence of random numbers each time you run it. This occurs because computers can’t generate truly random values. To ensure that the random numbers generated are truly random, you can seed the random number generator using the math.randomseed() function and pass in the current time. Since you’ll likely never run the script at the same time, this results in the randomseed() function being seeded with a unique value on each run.

math.randomseed(os.time())  -- Provide a random seed value to the random number generator
print(math.random())

You can also pass one or two arguments to the math.random() function:

print(math.random(10))  -- Maximum value is 10

print(math.random(10, 100)) -- Prints a random number between 10 and 100

Two other commonly used math functions are floor() and ceil():

print(math.floor(10.75))  -- Rounds a number down to the next integer,prints 10

print(math.ceil(10.75))  -- Rounds a number up to the next integer, prints 11

The math library module contains many mathematical functions such as sin, cos, tan, and many more. Check out the Lua documentation for more information.

Getting User Input

Interacting with users is an essential part of many programs, and Lua provides a straightforward way to get input from the user. The io.read() function is the primary way to accept user input in Lua.

Reading a Single Line of Input

The simplest way to get input from the user is to use io.read() without any arguments. This will read a single line of input from the user and return it as a string.

print("What is your name?")
local name = io.read()
print("Hello, " .. name .. "!")

Reading a Specific Type of Input

You can specify the type of input you want to read by passing an argument to io.read(). The available options are:

  • "n": reads a number
  • "l": reads a line of input
  • "a": reads the entire input as a string
  • "w": reads a word
print("Enter your age:")
local age = tonumber(io.read("n"))
print("You are " .. age .. " years old.")

In this example, we use "n" to read a number, and then convert the input to a number using the tonumber() function.

Reading Multiple Inputs

You can read multiple inputs by calling io.read() multiple times, or by passing multiple format specifiers as arguments.

print("Enter your name and age:")
local name = io.read()
local age = tonumber(io.read())
print("Your name is " .. name .. " and you are " .. age .. " years old.")

Alternatively:

print("Enter your name and age:")
local name, age = io.read("*l", "n")
print("Your name is " .. name .. " and you are " .. age .. " years old.")

It’s important to note that the io.read() function reads the input as a string, so you may need to convert the input to the appropriate data type (e.g., using tonumber() for numbers) before using it in your program.

Also, be aware that the input is buffered, which means that the program will wait for the user to press Enter before processing the input. If you want to read input without waiting for the user to press Enter, you can use a third-party library like LuaSocket or consider using a different approach, such as reading from the command line arguments.

By mastering the techniques for getting user input in Lua, you’ll be able to create more interactive and user-friendly programs.

Conclusion

In this second lesson, you’ve expanded your Lua programming skills by delving into the core concepts of variables, conditional statements, functions, and loops.

You now understand how to declare and work with variables in Lua, including the differences between local and global variables, and the importance of variable scope. This knowledge will help you write more organized and maintainable code, as you’ll be able to properly manage the lifecycle and visibility of your data.

We’ve also explored Lua’s rich set of conditional statements, including the if-then-else structure, the ternary operator, and the elseif and switch/case-like constructs. These tools allow you to make decisions and control the flow of your program based on various conditions, a fundamental skill for any programmer.

Furthermore, you’ve learned about the power of Lua functions. By encapsulating reusable blocks of code into functions, you can write more modular, testable, and efficient programs. The ability to pass arguments to functions and return values will prove invaluable as you tackle increasingly complex programming challenges.

You’ve also gained a solid understanding of Lua’s loop structures, such as for, while, and repeat-until. These control structures enable you to automate repetitive tasks, iterate over data structures, and solve problems that require iterative solutions.

Lastly, you’ve learned to get input from the users of your programs. With this knowledge, you can now create useful programs such as calculators, games, and utility programs.

As you continue your Lua learning journey, remember to practice the concepts covered in this lesson by working through the provided exercises. Hands-on experience is the best way to solidify your understanding and prepare you for the more advanced topics that lie ahead.

In the next lesson, we’ll explore Lua’s powerful data structures, including tables and arrays, and delve into how to effectively work with and manipulate them. We will also touch on some advanced string topics. Stay tuned, and keep up the great work!

Exercises

  1. Variable Assignment and Manipulation:
  • Declare variables for your name, age, and favorite number.
  • Perform various arithmetic operations on your favorite number and print the results.
  1. Conditional Statements:
  • Write a Lua script that checks if a number is positive, negative, or zero, and prints the appropriate message.
  • Create a program that determines if a year is a leap year.
  1. Functions:
  • Write a function that takes two numbers as arguments and returns their sum, difference, product, and quotient.
  • Create a function that calculates the area of a rectangle given its length and width.
  1. FizzBuzz:
  • Implement the classic FizzBuzz problem using Lua’s conditional statements and modulus operator.
  1. Random Number Generation:
  • Write a Lua script that generates a random number between 1 and 100, and then prints whether the number is even or odd.
  • Modify the script to seed the random number generator using the current time.

Resources

Series Navigation<< Learning Lua Step-By=StepLearning Lua Step-By-Step (Part 3) >>

Leave a Reply

Your email address will not be published. Required fields are marked *