# Lua: Logical Operators

In the previous tutorial we learnt about 'if' statements and how we can execute certain pieces of code if a certain condition is true. In this tutorial we're going to expand on this and learn about three different things called logical operators, which can help enhance and empower the functionality we learnt about in the previous tutorial.

The first logical operator we're going to learn about is the 'and' logical operator. This operator is usually used to mash two conditions together - if one condition is true and another condition is true, then do something. You can probably already see how this would be helpful in creating 'if' statements with more complex conditions.

In Lua, the "and" logical operator is expressed by simply writing the `and` keyword between two conditions - so if we wanted to create an application which requires two conditions for it to execute a certain portion of code, we might write something like the following:

 ```1 2 3 ``` ``````if variable_number > 9000 and variable_number < 10000 then --If it's over 9000 _and_ less than 10000 print("Key '" .. variable_number .. "' is correct") end --It might be a nice idea to put an 'else' here ``````

The above code would work correctly if "variable_number" was a variable which existed, and the code inside the 'if' statement would execute if the variable contained a number over 9000 but less than 10000. An issue, however, would arise if input from the user was put into "variable_number" and then it was put through this comparison - the issue being that the input from the user will be in the form of a string, and Lua doesn't automatically convert strings in conditions to numbers (for a good reason, it could cause all kinds of problems), this unfortunately means that the conditions will always be false.

Luckily for us, Lua has a nice function which converts strings to numbers called `tonumber` - it will return, what we call it when a function gives a value back to us, the number that the string is converted to if the string has been converted successfully, and it will return `nil`, the data type in Lua for expressing the concept of 0 or 'nothing', if the string could not be converted. As such, we can use this on a string received from the user to convert it into a number value, and display an error message if the conversion was not successful, with something like the following:

 ```1 2 3 4 5 6 7 8 9 10 11 12 ``` ``````io.write("Enter an ID number: ") identification_number = tonumber(io.read()) if identification_number == nil then print("Invalid ID number.") else if identification_number > 9000 and identification_number < 10000 then --If it's over 9000 and less than 10000 print("Key, '" .. identification_number .. "', is valid.") else print("Access denied.") end end ``````

Notice that I wrapped the whole of the if statement we previously formulated in an 'else' section so it will be executed if the ID is a valid number. Statements can be nested like this without problems in Lua (which is awesome!). Also note that `elseif`s could be used here, but in this case it makes more sense to me to have separate 'if' blocks.

The next logical operator we're going to talk about is the 'or' operator. It functions much like the 'and' operator that we just talked about, however checks if one condition or another is true rather than if both are true (and if both are true, it will also be true). It's used exactly like the 'and' operator, and so without much explanation, some code which utilises the `or` logical operator is as follows:

 ```1 2 3 4 5 6 7 8 ``` ``````io.write("Enter your username: ") username = io.read() if username == "joe" or username=="admin" then print("Access granted.") else print("Username not recognised.") end ``````

The code above will work fine, however issues could occur if users of the extremely primitive system used capital letters in their names - for example if "Joe" was written in instead of "joe". This problem can be solved by using the `string.lower` function, which makes all characters in a string lowercase. A modification like the following should solve this problem:

 ```1 2 3 4 5 6 7 8 9 ``` ``````io.write("Enter your username: ") username = io.read() username = string.lower(username) if username == "joe" or username=="admin" then print("Access granted.") else print("Username not recognised.") end ``````

The last logical operator we're going to be talking about in this tutorial is a little bit different. Instead of using the operator to conjoin two conditions, we use the operator to essentially flip something to its opposite state. This operator is called the 'not' operator. If we have anything that returns `true`, the `not` operator will change it to `false`, and the inverse is true for `false` being switched to `true`.

A nice way to think about it is that "not true" is false, and "not false" is true. As hinted at by the previous sentence, the 'not' operator in written in Lua by simply writing `not` before the thing you want to flip. If can be used in a similar sense to `and` and `or` in 'if' statements to flip a condition. Also remember that a basic `true` or `false` value will actually suffice fine as an 'if' statement condition, so something like the following would work fine:

 ```1 2 3 4 5 ``` ``````boolean_variable = true if not boolean_variable then --If not true (false) --Code here will never execute with boolean_variable being 'true' end ``````

Apart from this classic usage of `not`, which is commonly used for flipping boolean (true or false) variables and for flipping the return values of functions, the `not` operator can also be useful in other areas. There may, for example, be a situation in which our Lua script needs to toggle the value of a boolean variable with an unknown initial value. If it's true then we want it to be false, and if it's false then we want it to be true. We could write some 'if' statement logic to accomplish these simple goals, however a much more elegant solution would be to set the variable to `not` itself. Something like the following would do the job excellently:

 ```1 2 3 4 ``` ``````boolean_variable = true boolean_variable = not boolean_variable --Essentially toggle the variable state print(boolean_variable) --Output the result ``````