├── .gitignore
├── LuaGuide.md
├── LuaGuideFormatted.md
├── gen.sh
└── pictures
├── change-interpreter.png
├── create-directory-01-desktop.png
├── create-directory-02-name-directory.png
├── create-directory-03-rename-directory.png
├── create-file-01-file-new.png
├── create-file-02-untitled.png
├── create-file-03-file-save.png
├── create-file-04-file-dialog.png
├── create-file-05-file-dialog-desktop.png
├── create-file-06-file-dialog-name.png
├── installing-zerobrane-01-homepage.png
├── installing-zerobrane-02-download-page.png
├── installing-zerobrane-03-download.png
├── installing-zerobrane-04-choose-installer-location.png
├── installing-zerobrane-05-determine-architecture.png
├── installing-zerobrane-06-run-installer.png
├── installing-zerobrane-07-select-install-location.png
├── installing-zerobrane-08-choose-install-location.png
├── installing-zerobrane-09-welcome-screen.png
├── installing-zerobrane-10-create-shortcut.png
├── installing-zerobrane-11-shortcut-dialog.png
├── installing-zerobrane-12-choose-path.png
├── installing-zerobrane-13-finalize-path.png
├── installing-zerobrane-14-choose-name.png
├── installing-zerobrane-15-result.png
├── run-console-01-change.png
├── run-console-02-output.png
├── run-project-01-run-dialog.png
└── run-project-02-output.png
/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
3 | # Swap
4 | *.swp
5 |
--------------------------------------------------------------------------------
/LuaGuide.md:
--------------------------------------------------------------------------------
1 | # An Introduction to Lua
2 |
3 | ## Introduction
4 |
5 | Learning how to program is a very rewarding experience. Whether you're learning for school, your career, or just for fun, programming is a useful skill and does not need to be hard or complicated.
6 |
7 | ### Purpose
8 |
9 | The purpose of this guide is to take a person who knows little to nothing about programming and to teach them Lua (version 5.2, though all versions numbered with a '5' as the first number should be very similar). By the end of the tutorial, the reader should be able to read and write Lua with general ease.
10 |
11 | ### Why Lua?
12 |
13 | You may be wondering: "Why should I learn Lua?" There are several features of Lua that make it ideal as a first language:
14 |
15 | - Lua is a small language. This means that it has very few built-in commands. While this may not seem like an advantage at first, there are a few reasons why this is beneficial:
16 |
17 | - It makes the language easier to learn.
18 |
19 | - It reinforces concepts. Because many aspects that other languages have are not present by default in Lua, you gain a better understanding of how the concept works by implementing it yourself.
20 |
21 | - The main thing to keep in mind when programming is that computers are very literal. You have to tell the computer step-by-step what exactly you want it to do and how to do it. How much detail you include depends on the language you're using: Lua is good because it allows you to program without dealing with unnecessary complications for beginners like "memory allocation" and things like that. While these are useful for more advanced programmers, for beginners, these tend to be complicated and confusing.
22 |
23 | - Lua is more forgiving than many languages. Many languages feature complex and confusing processes, such as "static typing" and "compiling." These can be confusing for first-time users. Because Lua does not feature concepts like these, there will be at no point a concept where the reader is told to "Just trust me" (though I will delay explaining some topics fully until later in order to avoid confusion). Throughout this tutorial I will make an effort to explain not only how, but also why things are the way they are.
24 |
25 | - Installing Lua is very simple and straightforward.
26 |
27 | ### Thinking Like a Computer
28 |
29 | Earlier, I mentioned that, when programming, you need to tell the computer what to do with step-by-step instructions. This can be difficult for people to get used to at first; they expect the computer to "know what they mean," which rarely happens. Think of a computer as a very literal person who does **exactly** what you tell them to. For instance, most people would be able to follow these instructions and understand what is going on:
30 |
31 | 1. Set the toaster to the desired setting
32 |
33 | 1. Put in bread as desired
34 |
35 | 1. Retrieve the toast when it is ready
36 |
37 | 1. Butter to taste
38 |
39 | Anybody can read this and know that you are making toast, and will be able to follow this recipe without difficulty. If you told a very literal robot chef to do this, however, you would run into a few problems. First of all, you never told the robot chef to retrieve the bread initially. Additionally, it probably has no idea what "as desired", "to taste", or similarly vague phrases mean.
40 |
41 | When programming, you need to understand that the computer does *not* know what you are trying to do, nor does it care. It will do exactly what you tell it to do; nothing more, nothing less.
42 |
43 | ### Installing and Setting up an Editor
44 |
45 | In order to edit code, you need something called a **text editor**. An editor is what you use to write your code. Editors can be as simple or complex as you would like them to be. You can even use Notepad to edit your Lua files, though I would **strongly** advise against this for several reasons. Primarily, it lacks syntax highlighting, which makes your code easier to read. It also lacks an advanced undo structure, which severely limits your ease-of-use. For most entry-level users, I recommend installing ZeroBrane, an **IDE**, or **Integrated Development Environment** for Lua. What does "integrated development environment" mean? Basically, it makes programming in Lua easier by aiding in some common tasks. One big advantage is that it comes installed with several versions of Lua and is very easy to install. The installation process is as follows:
46 |
47 |
49 |
50 | 1. Go to [studio.zerobrane.com](https://studio.zerobrane.com)
51 |
52 | 1. Select the "Download" tab on the right side of the page
53 |
54 |
55 |
56 | 1. Select the option "*Take me to the download page this time*" for now (unless you're feeling generous). This program is available for free, but you can fund the development now (or at a later date) if you desire.
57 |
58 |
59 |
60 | 1. Select "*Windows 32bit (exe installer)*" (assuming that you are on Windows, of course!)
61 |
62 |
63 |
64 |
65 | 1. If you get the option to choose where the installer is downloaded, put it in your "*Downloads*" directory
66 |
67 | 1. Once you've selected the directory, click "Save" (*You may not see these steps if you have not configured your internet browser to allow you to choose where your downlaods go*)
68 |
69 |
70 |
71 | 1. Now you need to figure out if your computer is 32 or 64 bits. If you're not sure, open the File Explorer and go to "C:\\". This will be found either under "This PC" or "My Computer" depending on the age of your computer. If you have a directory called "Program Files (x86)", as pictured here, you are using a 64 bit computer; if not, you're using a 32 bit computer.
72 |
73 |
74 |
75 | 1. Now, run the installer. This can be done by navigating to the directory where it was downloaded and double-clicking the installer. It should be called something like "*ZeroBraneStudioEduPack-1.60-win32.exe*". If you were not able to choose where the download goes, look in your "*Downloads*" folder or see if your internet browser will display the location where it was downloaded.
76 |
77 |
78 |
79 | 1. When you run the installer, you should be greeted by this pop-up dialog box. If you can't read the text, try holding `Ctrl` and moving your mouse wheel. Select the text under the heading "*Destination folder*" so that it appears blue, like pictured above.
80 |
81 |
82 |
83 | 1. Now you need to choose where the program should be installed. For 64 bit systems, install the program in "*C:\\Program Files (x86)\\ZeroBrane*" and for 32 bit systems, install the program in "*C:\\Program Files\\ZeroBrane*". Note that the location does not matter that much; it's just good practice to put files in these locations so that they are easier to find later on. While installing, you will probably be asked to grant administrator privileges. Allow the program to run with administrator privileges in order to install successfully.
84 |
85 |
86 |
87 | 1. Once the installation is completed, you should be greeted with a screen that looks like this. Congratulations! Your installation is complete.
88 |
89 |
90 |
91 | 1. Next you will want to create a shortcut on your desktop so that it is easier to run the program. To do this, close or minimize all open windows and right-click on the desktop (**not** one of the icons). Move the mouse down until you see the "*New*" option.
92 |
93 | 1. From the new menu, choose the option "*Shortcut*" to create a shortcut on your desktop.
94 |
95 |
96 |
97 | 1. You should be greeted with a prompt that looks something like the above. Select "*Browse*" to locate the program.
98 |
99 |
100 |
101 | 1. Navigate to the location of the ZeroBrane Studio executable. If you followed the steps above, it should be in "*C:\\Program Files (x86)\\ZeroBrane\\*" or "*C:\\Program Files\\ZeroBrane\\*". Select the executable called `zbstudio`. (*Note that the "C:\\" directory is located in either "This PC" or "My Computer" depending on the age of your system*)
102 |
103 | 1. Once you have selected the executable, select "*OK*" to continue.
104 |
105 |
106 |
107 | 1. Once the program has been selected, its path should appear, like so. Choose "*Next*" to continue.
108 |
109 |
110 |
111 | 1. Give a name to the program. The name does not matter, so you can change the name if you want. Just make sure that it makes sense. For instance, you could change the name from "*zbstudio*" to "*ZeroBrane*" if you wanted. When you're done, click "*Finish*."
112 |
113 |
114 |
115 | 1. Now you should have a shortcut on your desktop, as you see here. If you double-click this icon you will launch ZeroBrane studio, bringing you to the same screen that you saw before.
116 |
117 | ### Format of this Guide
118 |
119 | This guide is broken into several logical sections. In order to keep yourself organized, and make it easier to review your notes, I recommend making a folder on your desktop that will contain several folders within it.
120 |
121 | #### Creating a Directory for This Guide
122 |
123 | Creating a directory is simple and easy to do, as demonstrated below:
124 |
125 |
126 |
127 | 1. Close or minimize all open windows and right-click on your desktop (**not** on an icon).
128 |
129 | 1. Move your mouse over to the "*New*" option.
130 |
131 | 1. Select the option "*Folder*".
132 |
133 |
134 |
135 | 1. Now you should have a new folder created on your desktop, as pictured above.
136 |
137 |
138 |
139 | 1. Give the folder a name that will help you identify it later, like "*Lua*" or something like that.
140 |
141 | Now you should be ready to keep all of your files organized in one place.
142 |
143 | #### Changing the Interpreter
144 |
145 | At the beginning of the guide, I said that the version of Lua that you'll be learning is Lua 5.2. While the versions are all fairly similar, some minor discrepancies exist from version to version. In order to keep any of these discrepancies from occurring, the interpreter will need to be changed in order to reflect this. The **interpreter** is what runs the Lua scripts that you write. It converts your code into something that the computer can understand and use. Changing the interpreter is very easy to do, as can be seen below:
146 |
147 |
148 |
149 | 1. Open up ZeroBrane and move your mouse to the "*Project*" heading.
150 |
151 | 1. Move your mouse down to the "*Lua Interpreter*" section.
152 |
153 | 1. Select the version "*Lua 5.2*".
154 |
155 | Now your program will be run using the Lua 5.2 interpreter.
156 |
157 | #### Running the Console
158 |
159 | Each sections in this guide is composed of two parts: **Instruction** and **Exercises**. In the instruction section, commands are entered through ZeroBrane's interactive console. In the exercises section, a file is created and run.
160 |
161 | The interactive console can be run like so:
162 |
163 |
164 |
165 | 1. At the bottom of ZeroBrane's window, you should see three tabs, as pictured above.
166 |
167 |
168 |
169 | 1. Move your mouse over to the one labeled "Local console" and select it. You should now see the above text telling you that you are working with the interactive Lua interpreter, also known as the console.
170 |
171 | #### Creating a New File
172 |
173 | In the exercises section, the entire file is executed all at once. You can create these files using ZeroBrane, as demonstrated below:
174 |
175 |
176 |
177 |
178 | 1. At the top of the ZeroBrane window, move your mouse over to "*File*".
179 |
180 | 1. Select the option "*New*".
181 |
182 |
183 |
184 | 1. You should now have a new tab open up next to the "*Welcome*" tab, like so.
185 |
186 |
187 |
188 | 1. With the file you want to save selected, go to the "*File*" heading.
189 |
190 | 1. Select the "*Save*" option. The first time that you save the file, you should get a pop-up dialog asking you where you would like to save it, as shown below.
191 |
192 |
193 |
194 | 1. You will want to keep all of your files located in logical places so that they are easier to find, such as the folder you made earlier. For this tutorial, I recommend saving all of your files in a folder on your desktop. To do this, select the "*Desktop*" option on the side of the file explorer, as pictured above. If you do not see this option, you will have to go to "*C:\\Users\\YOURNAME\\Desktop\\*", where *YOURNAME* is your username on your computer.
195 |
196 |
197 |
198 | 1. To select the folder that you created earlier, either double-click the folder or select the folder then click "*Open*".
199 |
200 |
201 |
202 | 1. Give the file a name by clicking in the box labeled "*File name:*" and giving it a name that you desire, then clicking "*Save*". Here, I have named my program "*test.lua*".
203 |
204 | Once you have created the file, it can be run using the IDE, as demonstrated below.
205 |
206 | #### Running the File
207 |
208 | In the exercises code sections, files are run. Running a file is simple and will comprise the majority of what you do when you're programming.
209 |
210 |
211 |
212 | 1. Create a new blank file, as demonstrated in the section [Creating a New File](#creating-a-new-file).
213 |
214 | 1. Move your mouse over to the "*Project*" heading
215 |
216 | 1. Select the first option, "*Run*".
217 |
218 |
219 |
220 | 1. You should see the text below when you run a file. Each line contains information about your program:
221 |
222 | 1. The first line tells you initial settings and information:
223 |
224 | 1. The location of the Lua interpeter that you are using (`"C:\Program Files (x86)\ZeroBrane\bin\lua52.exe"`).
225 |
226 | 1. The `-e io.stdout:setvbuf('no')"` is a command that is executed before the code is run. Basically, it makes viewing the output easier.
227 |
228 | 1. The location of the file being run (`"C:\Users\User\Desktop\Lua\test.lua"`).
229 |
230 | 1. The second line tells you information about the "*project*", which is how ZeroBrane groups Lua files:
231 |
232 | 1. `lua52.exe` is the name of the interpreter. This shows that it was started and its directory.
233 |
234 | 1. The directory `"C:\Program Files (x86)\ZeroBrane\myprograms"` refers to the *directory* of the Lua file. The directory allows you to use multiple files together at once.
235 |
236 | 1. The third line tells you about the details from the script execution:
237 |
238 | 1. It ran in `0.05` seconds.
239 |
240 | 1. Its **PID**, or Process Identification Number, is 8600. This number is used by ZeroBrane to keep track of your script while its running and this PID will be different for every script invocation.
241 |
242 |
243 | ## Variables
244 |
245 | Variables contain values. These values can be of several types: `strings`, `numbers`, `booleans` and more. The type of a variable represents how it can be used and what it is used for. Variables are the building blocks of all good code and are an extremely important concept to understand.
246 |
247 | ### Variable Names and Comments
248 |
249 | Variables in Lua can be any series of letter or numbers, as long as they don't start with a number (the reasoning for this will be given later). Variables can also contain underscores, but no other special characters. This is because most of these characters are operators, such as addition or subtraction. The following are all *valid* variable names (note that you should **not** run the following in the interpreter):
250 |
251 | ```lua
252 | variable
253 | name123
254 | this_name
255 | luaIsAwesome
256 | ```
257 |
258 | The following are all **not** valid variable names (you should **not** run this section either):
259 |
260 | ```lua
261 | 2songName -- Variables cannot start with numbers
262 | this variable -- Variables cannot have spaces
263 | lua-is-awesome -- Variables can only have underscores, letters, and numbers
264 | ```
265 |
266 | You may have noticed the "`--`" above. These are called **single-line** or **one-line comments**. Anything after these two dashes is ignored by the interpreter. Comments can be used to document your code. The space after `--` does not have to be present, though I prefer the way it looks with it.
267 |
268 | You can also do **multi-line** or **block comments**, which are like comments, but span multiple lines. They are opened with "`--[[`" and closed with "`]]`". Note that with multi-line comments, there must be **no** space between `--` and `[[`. You can use multi-line comments, for example, to make notes about valid variable names. Open up the command line and type `lua` to go into interactive mode and type the following:
269 |
270 | ```lua
271 | --[[
272 | Valid variable names:
273 | ---------------------
274 | variable
275 | name123
276 | this_name
277 | luaIsAwesome
278 |
279 | Invalid variable names:
280 | -----------------------
281 | 2songName -- Variables cannot start with numbers
282 | this variable -- Variables cannot have spaces
283 | lua-is-awesome -- Variables can only have underscores, letters, and numbers
284 | ]]
285 | ```
286 |
287 | Notice how nothing happens when you finish. That is because you aren't doing anything yet. Remember, comments are ignored by the interpreter, so this is essentially the same as just hitting enter.
288 |
289 | In the above examples, you may have noticed that there are many ways to format variable names. There are two prevailing ways to separate words:
290 |
291 | ```lua
292 | variableNamesLikeThis
293 |
294 | -- or
295 |
296 | variable_names_like_this
297 | ```
298 |
299 | The first is called `camelCase` and the second is called `snake_case`. In this tutorial I will use camel case simply because I prefer it, though both methods are perfectly valid.
300 |
301 | Note that capitalization **does** matter: `thisVariable` is different from `THISVARIABLE` and so on.
302 |
303 | Variable names should be short but descriptive. The descriptive part is of more importance than the short part, however. Your variable name needs to be descriptive to help you remember the purpose of the variable. When in doubt, go with verboseness over conciseness. This will save you headaches in the long run, by keeping you from having to search all over the place for what your variable represents.
304 |
305 | ### Assigning and Accessing Variables
306 |
307 | You **assign** variables with an equal sign. Assigning a variable just means that you are giving the variable a value. Variable assignment looks like this:
308 |
309 | ```lua
310 | variableName = value
311 | ```
312 |
313 | **Accessing** variables is done by referencing the name of the variable. For instance, if you wanted to view the value of a variable, you would do so like so (enter this into the Lua command line):
314 |
315 | ```lua
316 | variableName = 5
317 | print( variableName ) -- 5 (You do not need to write comments)
318 | ```
319 |
320 | The `print` command is used to show the output of values and is part of Lua's **standard library**. It is called a **function**. A function is something that will be explained more later, but essentially it is used to make programming easier.
321 |
322 | ### Variable Types
323 |
324 | In (virtually) all programming languages, variables have what are called "types." The type of a variable dictates what the variable is used for. There are several types of variables, but the most common are `numbers` `strings`, and `booleans`.
325 |
326 | #### Numbers
327 |
328 | In the above example, `variableName` must conform to the variable naming specifications (see [Variable Names and Comments](#variable-names-and-comments) for more) and `value` can be virtually anything. For instance, if you wanted to assign a variable to the value of pi, you could do:
329 |
330 | ```lua
331 | pi = 3.14
332 | print( pi ) -- 3.14
333 | ```
334 |
335 | In this example, the variable assigned is a **number**. As mentioned before, there are many types of values a variable can store, and each type has different uses. Numbers, for instance, are used for mathematical operations.
336 |
337 | Numbers can be stored in many different formats. For instance, if you wanted to represent a number in scientific notation, you could do the following:
338 |
339 | ```lua
340 | speedOfLight = 3e8
341 |
342 | -- or
343 |
344 | speedOfLight = 3E8
345 |
346 | print( speedOfLight ) -- 300000000
347 | ```
348 |
349 | Numbers can also be stored in hexadecimal with the following notation:
350 |
351 | ```lua
352 | fourteen = 0xE
353 | fourteen = 0XE
354 | print( fourteen ) -- 14
355 | ```
356 |
357 | Note that hex numbers **must** be preceded with `0x` or `0X`. This is the representation used to store hexadecimal numbers, as well as part of the reason that variable names in Lua cannot be started with numbers, as there would be ambiguity as to whether you are referencing a number or assigning a variable.
358 |
359 | You can also perform operations and store those values as numbers. For instance:
360 |
361 | ```lua
362 | pi = 3.14
363 | r = 1
364 | area = pi * r ^ 2
365 | print( area ) -- 3.14
366 | ```
367 |
368 | Note that numbers are evaluated in the same way that you follow order of operations, though parenthesis can be used for clarity if desired.
369 |
370 | You can also use a variable in its own assignment if it already has a value. For instance, increasing a number by one is called **incrementing** and decreasing a variable by one is called **decrementing**. This is done like so:
371 |
372 | ```lua
373 | numberOfSongs = 3
374 |
375 | -- Later, say when a song is added:
376 | numberOfSongs = numberOfSongs + 1
377 | print( numberOfSongs ) -- 4
378 | ```
379 |
380 | #### Strings
381 |
382 | The `string` type is used to store characters. They're called `strings` because they contain a "string," or series of characters. The name is somewhat confusing, but their usage isn't. They're used to store virtually any information that won't be used as a number or in mathematical operations. Strings are surrounded by single quotes or double quotes. The following are all strings:
383 |
384 | ```lua
385 | state = "North Carolina"
386 | country = 'United States of America'
387 |
388 | print( state ) -- North Carolina
389 | print( country ) -- United States of America
390 | ```
391 |
392 | Note that you must open and close the string with the same type of quote. Both formats are valid, though I prefer to use single quotes because they're easier to type, so that is what I will use throughout the tutorial.
393 |
394 | It is possible to mix single and double quotes, like so:
395 |
396 | ```lua
397 | sentence = 'She said "No way Jose!"'
398 | response = "I said \"Yes way Jose!\""
399 |
400 | print( sentence ) -- She said "No way Jose!"
401 | print( response ) -- I said "Yes way Jose!"
402 | ```
403 |
404 | Note the `\"` in the second example. This is called "escaping" and is used to contain double quotes in a string surrounded by double quotes. Basically, what these do is tell Lua that these quotes are part of the string and do not represent the end of the string. Note that, because we used single quotes in the first example, there was no need to escape the double quotes (though escaping the double quotes there wouldn't be wrong). Single quotes can also be escaped.
405 |
406 | Just as there are operators you can do on numbers, there are operators you can use on strings. You can combine strings with the "`..`" operator. This is called **concatenating** strings. You can concatenate multiple strings at once.
407 |
408 | ```lua
409 | part1 = 'this'
410 | part2 = 'is'
411 | part3 = 'a'
412 | part4 = 'test'
413 |
414 | sentence = part1 .. ' ' .. part2 .. ' ' .. part3 .. ' ' .. part4
415 | print( sentence ) -- this is a test
416 | ```
417 |
418 | Note that strings can be concatenated even if they are not already assigned to a variable, as shown in the above demonstration, where the variables have already been assigned while the spaces (`' '`) have not.
419 |
420 | #### Multi-Line Strings
421 |
422 | Just as comments can be multiple lines, strings can also be multiple lines. The syntax for multi-line strings is very similar to multi-line comments. Recall that multi-line comments look like so:
423 |
424 | ```lua
425 | --[[
426 | This is a
427 | multi-line comment
428 | ]]
429 | ```
430 |
431 | This is what multi-line strings look like:
432 |
433 | ```lua
434 | mutliLineString = [[
435 | This text is part of
436 | a multi-line string.
437 |
438 | You can use both "double"
439 | and 'single quotes'
440 | without worrying
441 | ]]
442 |
443 | print( multiLineString )
444 | ```
445 |
446 | Note that the line after `without worrying` **is** present. To get rid of this extra line, simply put the `]]` on the same line as `without worrying`. Also note that the first line after `[[` is ignored.
447 |
448 | #### Booleans
449 |
450 | If numbers store numbers and strings store strings of characters, what do booleans store? Booleans store values that represent "thruthiness." Booeleans have two values: `true` or `false`.
451 |
452 | ```lua
453 | luaMaster = false
454 | luaLearner = true
455 |
456 | print( luaMaster ) -- false
457 | print( luaLearner ) -- true
458 | ```
459 |
460 | Booleans are useful when dealing in absolutes. For instance, if you had a variable `carIsRunning`, you would probably use a boolean to represent if the car is running or not, because the car can either be on or off. A car cannot be between running and not running; that's not possible. Similarly, something that a variable represents may only be in two states. Booleans are used to represent these variables.
461 |
462 | #### Nil
463 |
464 | Nil is a special type of value in Lua. It is the value used when a variable is not assigned. For instance, take the example below:
465 |
466 | ```lua
467 | Index = 1
468 | print( index ) -- nil
469 | ```
470 |
471 | Note here that the variable assigned is `Index`, while the variable accessed is `index`. Because these are different variables (remember: capitalization matters), `index` has not been assigned, so it has no value. So, `nil` is the value given to variables who have not been assigned.
472 |
473 | You may be wondering: Why is this useful? Why can't Lua just figure out what variable I'm going for instead of being so pedantic? Because you don't want your programming language to try to "figure out" anything; it should do **only** what you tell it to. This is because you can get hard to find errors if the program thinks you're trying to type one thing and you mean another.
474 |
475 | Additionally, having the `nil` value is useful for several somewhat complex reasons. These will be explained more later, but what you need to know now is that it allows you to check if a variable has been assigned or not.
476 |
477 | ### The `type` Command
478 |
479 | Just like the `print` command is a part of Lua's standard library, so to is another command: `type`. The `type` command is used to get a variable's type. For instance, if you ran
480 |
481 | ```lua
482 | print( type( 3 ) ) -- number
483 | ```
484 |
485 | You would get `number`. That's because `3` is a number. You can see all the variable types represented:
486 |
487 | ```lua
488 | print( type( 'This is a string' ) ) -- string
489 | print( type( true ) ) -- boolean
490 | print( type( nil ) ) -- nil
491 | ```
492 |
493 | This command is useful for getting information about a variable.
494 |
495 | ### Why would I want to use variables?
496 |
497 | Variables are extremely useful and are the building blocks for a program. Variables hold many benefits for programmers:
498 |
499 | - Variables make your code easier to read and understand. Variables are more descriptive than just numbers or strings. You may not know exactly what `d = 6.28 * r` means or does, but you know exactly what it represents in the example below:
500 |
501 | ```lua
502 | pi = 3.14
503 | tau = 2 * pi
504 | radius = 5
505 | diameter = tau * radius
506 | ```
507 |
508 | - Variables make changing your code easier. For instance, say your program gets the area and circumference of a circle. This is what your program looks like:
509 |
510 | ```lua
511 | radius = 3
512 | area = 3.14 * radius ^ 2
513 | circumference = 2 * 3.14 * radius
514 | ```
515 |
516 | - What happens if you decide you want more precision with your results? You would be forced to change every occurrence of `3.14` with whatever the new value is. Of course, in this example, that's only two times. But you can imagine how much of a pain it would be in an actual program. It's easier to use a variable for `pi`, and to just change that one value instead of every individual value, avoiding wasted time and frustration.
517 |
518 | In summary, variables:
519 |
520 | - Make your code easier to read
521 |
522 | - Make changes easier and faster
523 |
524 | #### Strings vs Numbers
525 |
526 | You may have noticed that strings can store numbers. This may have caused you to ask yourself, "How do I decide if I should use a number or a string?" The answer is "It depends." For a simple answer, numbers that you will be doing mathematical calculations with should be `numbers`, while numbers that will only be stored or displayed should be `strings`. For instance, a phone number would usually be stored as a `string`, as no calculations will be done with a phone number. On the other hand, a person's age would probably be stored as a `number`, as, at the very least, it will need to be incremented.
527 |
528 | ### Exercises
529 |
530 | In this section, you will create a file that should act as your notes. Feel free to add comments liberally to document what it is you're doing and why. I recommend making a directory on your `Desktop` to keep all of your files, and naming this file something really clever like `01 Variable Names and Comments.lua` and opening it with ZeroBrane. Type the following information to the file:
531 |
532 | ```lua
533 | info1 = 'This is a string'
534 | info2 = 'Strings can store letters and numbers'
535 |
536 | print( info1 )
537 | print( info2 )
538 | ```
539 |
540 | Now run the project. If you've followed the instructions correctly, the console should output something like this:
541 |
542 | ```
543 | This is a string
544 | Strings can store letters and numbers
545 | ```
546 |
547 | Next, you will want some notes on variable names:
548 |
549 | ```lua
550 | thisIsCamelCase = true
551 | this_is_snake_case = true
552 |
553 | print( thisIsCamelCase )
554 | print( this_is_snake_case )
555 |
556 | 1invalidName = true
557 | also bad = true
558 | don't-bother = true
559 | ```
560 |
561 | When you run the file you should see an error that says something like:
562 |
563 | ```
564 | lua: 01 Variables and Comments.lua:13: unexpected symbol near '1'`
565 | ```
566 |
567 | Let's break down this error:
568 |
569 | - `lua:`: This tells you that the error is a Lua error.
570 |
571 | - `01 Variables and Comments.lua`: This is the file in which the error occurs.
572 |
573 | - `13:` This tells you the line on which the error occurred. If the line isn't exactly 13, don't worry. (In fact, it should probably be past 13 because of all the comments you've added!)
574 |
575 | - `unexpected symbol near '1'`: This tells you that there is something that was not expected near `1`. If you remember from earlier, variable names in Lua cannot start with numbers. To get rid of this error, change that line to something like this:
576 |
577 | ```lua
578 | -- 1invalidName = false
579 | -- Variable names can't start with numbers!
580 | ```
581 |
582 | When you run the file again, you should get another error:
583 |
584 | ```
585 | lua: test.lua:14: syntax error near 'bad'
586 | ```
587 |
588 | This time, the syntax error is near `bad`. This is because variables in Lua cannot have spaces! The Lua interpreter is expecting something after the space, such as a comma or equal-sign. To get rid of this, comment out the line and add some notes.
589 |
590 | When you run the file again, you should get yet another error:
591 |
592 | ```
593 | lua: test.lua:15: unfinished string near ''t-bother = true'
594 | ```
595 |
596 | This is because the `'` indicates the start of a string. In Lua, strings can't be multiple lines. (Actually, they can, but you need to use special characters to indicate this). At any rate, the string isn't enclosed, so the error is still valid. Get rid of the quote to get rid of that error message, and add a comment noting so. Now, you're greeted with a new error:
597 |
598 | ```
599 | lua: test.lua:15: syntax error near '-'
600 | ```
601 |
602 | This is because you can't have dashes within a variable name. Comment out the line to get rid of the error.
603 |
604 | Now add the following:
605 |
606 | ```lua
607 | booleanVariable = true
608 | stringVariable = 'string'
609 | numberVariable = 123
610 | multiLineString = [[
611 | This is a
612 | string that spans
613 | mutliple lines
614 | ]]
615 |
616 | --[[
617 | This comment also
618 | spans mutliple lines
619 | ]]
620 |
621 | print( booleanVariable )
622 | print( stringVariable )
623 | print( numberVariable )
624 | print( multiLineString )
625 | print( thisVariableIsNil )
626 | ```
627 |
628 | **Remember**: This is supposed to serve as *your* notes. Add more if you think it's necessary. (You should have **much** more than I have here).
629 |
630 |
631 |
632 |
633 |
634 | ## Basic Loops
635 |
636 | Sometimes when you are programming, there will be a task that is repeated many times. For instance, say you want to print your name five times. You could write something that looks like this:
637 |
638 | ```lua
639 | name = 'John Smith'
640 |
641 | print( name )
642 | print( name )
643 | print( name )
644 | print( name )
645 | print( name )
646 | ```
647 |
648 | As a programmer, you should strive to be as lazy when typing as possible. This means that the above code is a big no-no. The main reason for this is that it is difficult to change. Say, for instance, you want to print your name 10 times. That means copying and pasting everything. (***Hopefully*** you didn't consider typing all of that!) This is unwieldy, but manageable. But what happens if you want to print your name ***100*** times? This would be a real pain to type and would be ridiculous. But what about a **variable** number of times? This would be impossible with what you currently know. Thankfully, Lua includes a construct that is ideal for this type of situation: the `for-loop`.
649 |
650 | ### Numeric For-Loops
651 |
652 | Instead of writing everything multiple times, you can use what are called **numeric for-loops**. The name might be scary, but all it does is do something a certain number of times. This is the basic structure of this loop is (you should **not** run this):
653 |
654 | ```lua
655 | for VAR = START, END, INCREMENT do
656 | -- Code
657 | end
658 | ```
659 |
660 | In the above code, `VAR` is a variable that represents the current index of the loop. `START` represents the number at which the loop begins, `END` represents the number at which the loop stops, and `INCREMENT` is the amount by which to increase (or decrease) `VAR` at the end of each loop. If `INCREMENT` is not given, it defaults to `1`.
661 |
662 | Below is a basic example of a for-loop:
663 |
664 | ```lua
665 | for index = 1, 5, 1 do
666 | print( index )
667 | end
668 |
669 | --[[
670 | 1
671 | 2
672 | 3
673 | 4
674 | 5
675 | ]]
676 | ```
677 |
678 | Note that, because the increment is `1` by default, this loop is the same as
679 |
680 | ```lua
681 | for index = 1, 5 do
682 | print( index )
683 | end
684 | ```
685 |
686 | In most cases, you will want to increment by one, but you can increment by any real number. For instance, if you wanted even numbers, you could do:
687 |
688 | ```lua
689 | for i = 2, 10, 2 do
690 | print( i )
691 | end
692 |
693 | --[[
694 | 2
695 | 4
696 | 6
697 | 8
698 | 10
699 | ]]
700 | ```
701 |
702 | You can also use a variable as the `STOP` or increment. For instance, in the above example, where you wanted to print your name a certain amount of times, you would do something like this, changing `times` to the number of times you would like to print the person's name.
703 |
704 | ```lua
705 | name = 'John Smith'
706 | times = 100
707 |
708 | for index = 1, times do
709 | print( name )
710 | end
711 | ```
712 |
713 | This is **much** better than typing all of the original code out and changing it all the time.
714 |
715 | #### Using the Stop and Increment Controllers
716 |
717 | You may remember the parts of the for-loop labeled `STOP` and `INCREMENT` from before. These two variables work in conjunction with each-other to control how many times the for-loop loops. The loop will continue until the index will have surpassed `STOP`. Here are some examples of how different loops work:
718 |
719 | ```lua
720 | for i = 1, 8, 2 do
721 | print( i )
722 | end
723 | --[[
724 | 1
725 | 3
726 | 5
727 | 7
728 | ]]
729 |
730 | for i = 8, 1, -2 do
731 | print( i )
732 | end
733 | --[[
734 | 8
735 | 6
736 | 4
737 | 2
738 | ]]
739 | ```
740 |
741 | Note that in each of the above examples, if the loop would have executed one more time, the index would have surpassed `STOP`.
742 |
743 | ### While-Loops
744 |
745 | While loops rely on [booleans](#booleans) to control their flow. A while-loop executes **while** the condition is true. For instance, if you wanted to implement a simple incrementing for-loop, you would do something like this:
746 |
747 | ```lua
748 | index = 1
749 | while index < 5 do
750 | print( index )
751 | index = index + 1
752 | end
753 |
754 | --[[
755 | 1
756 | 2
757 | 3
758 | 4
759 | ]]
760 | ```
761 |
762 | A look at how the loop works helps to understand why it prints 1-4 and not 5. This is what the loop looks like at each step of execution (do **not** run the following code; it is simply an illustration of what is occurring):
763 |
764 | ```
765 | Is 1 < 5? Yes, so:
766 | print( 1 )
767 | index = 1 + 1 -- (index now is equal to 2)
768 | Check condition again
769 |
770 | Is 2 < 5? Yes, so:
771 | print( 2 )
772 | index = 2 + 1 -- (index = 3)
773 | Check condition again
774 |
775 | Is 3 < 5? Yes, so:
776 | print( 3 )
777 | index = 3 + 1
778 | Check condition again
779 |
780 | Is 4 < 5? Yes, so:
781 | print( 4 )
782 | index = 4 + 1
783 | Check condition again
784 |
785 | Is 5 < 5? No, so stop.
786 | ```
787 |
788 | Now it is obvious why 5 is not output: the loop only executes while the given condition is `true`, then quits.
789 |
790 | Note that it is **essential** to assign the variable *before* the while-loop. The concept is a bit complicated, but essentially, you can't compare `index` and `5` if `index` has no value yet. Consider the following example:
791 |
792 | ```lua
793 | index = nil
794 | while index < 10 do
795 | print( index )
796 | index = index + 1
797 | end
798 | ```
799 |
800 | Because you have not assigned `index` a value yet, you will get the error "Attempt to compare a number with [nil](#nil)." This is because you're essentially asking the interpreter to compare `nil` with `5`. Because `nil` has no value, you cannot compare it with a number, hence causing the error above.
801 |
802 | As long as the statement between the `while` and `do` is `true`, the loop will continue to repeat. The general structure of a while-loop is:
803 |
804 | ```lua
805 | while ( BOOLEAN ) do
806 | -- Code
807 | end
808 | ```
809 |
810 | `BOOLEAN` is a value that is updated every loop. If `BOOLEAN` is **not** updated every loop, you will end up with an **infinite loop**.
811 |
812 | #### Infinite Loops
813 |
814 | An infinite loop will execute until you terminate the execution. You can interrupt the execution of the process by pressing `Ctrl` and `c` at the same time. This tells the Lua interpreter to quit what it was doing and is called **breaking** the execution. For instance, type the following into the interpreter:
815 |
816 | ```lua
817 | while true do
818 | print( 'infinite' )
819 | end
820 | ```
821 |
822 | Notice that this will continue executing until you break it using `Ctrl+c`.
823 |
824 | #### Break
825 |
826 | There is also a command that can also be used to abort the execution of a loop called `break`. This is used if you want to stop the execution of a loop for any reason. Take the following example:
827 |
828 | ```lua
829 | index = 1
830 |
831 | while index < 5 do
832 | print( index )
833 | index = index + 1
834 | break
835 | print( 'You should not see this!' )
836 | end
837 | -- 1
838 |
839 | print( index ) -- 2
840 | ```
841 |
842 | Note that the code after the `break` command is not executed. This is because that part is completely ignored because of the `break` command.
843 |
844 | The `break` command ended the loop before the execution completed. This may not seem useful now, but it will become more useful later when you have learned about more advanced structures, such as `if-then` statements, which will be discussed in the next section.
845 |
846 | ### Repeat-Until Loops
847 |
848 | Repeat-until loops are very similar to `while` loops. While `while` loops execute execute **while** a condition is `true`, `repeat-until` loops execute until a condition is met. These two loops have the same output, but their structure is very different:
849 |
850 | ```lua
851 | -- while-loop
852 | i = 0
853 | while ( i < 5 ) do
854 | i = i + 1
855 | end
856 | print( i ) -- 5
857 |
858 | -- repeat-until loop
859 | i = 0
860 | repeat
861 | i = i + 1
862 | until ( i > 4 )
863 |
864 | print( i ) -- 5
865 | ```
866 |
867 | You may be wondering: What is the advantage of using a `while` loop versus a `repeat` loop? Personal preference is certainly one reason, but there is one other advantage: a `repeat` loop will **always** execute *at least* one time, while `while` loops may not execute at all. This may seem odd at first, but it makes sense: If the initial condition of a `while` loop is `false`, the loop never executes. Test the following loops out:
868 |
869 | ```lua
870 | i = 5
871 | while i < 5 do
872 | print( i )
873 | i = i + 1
874 | end
875 | -- No output from the loop
876 | print( i ) -- 5
877 |
878 | i = 5
879 | repeat
880 | print( i )
881 | i = i + 1
882 | until i > 4
883 | -- 5
884 | print( i ) -- 6
885 | ```
886 |
887 | Note that in both of `while` and `repeat` loops, you **can** surround the boolean expression with parenthesis if you'd like. In fact, all of the following are valid ways to express loops:
888 |
889 | ```lua
890 | i = 0
891 | while i < 5 do
892 | i = i + 1
893 | end
894 | print( i )
895 |
896 | i = 0
897 | while ( i < 5 ) do
898 | i = i + 1
899 | end
900 | print( i )
901 |
902 | i = 0
903 | while i < 5 do i = i + 1 end
904 | print( i )
905 | ```
906 |
907 | All of the following are valid, as well as several other ways. This is another one of the advantages of Lua: you don't have to format your code a certain way. As long as the entire word is complete (i.e. not separated by a space or new line), it doesn't matter how the code is formatted. I would **strongly** recommend avoiding the third method, however, as it is harder to read and understand.
908 |
909 | ### Exercises
910 |
911 | You may have noticed that for-loops, while-loops, and repeat-until loops can all be used to do the same things. Start by creating a file called `02 Basic Loops.lua` and creating a for-loop that counts from 1 to 10:
912 |
913 | ```lua
914 | for 1, 10, 1 do
915 | print( index )
916 | end
917 | ```
918 |
919 | You should get an error saying ` expected near '1'`. That's because you forgot to assign `index`! Fix it by changing the loop to:
920 |
921 | ```lua
922 | for index = 1, 10, 1 do
923 | print( index )
924 | end
925 | ```
926 |
927 | Now try going from 10 to 1 with a for-loop:
928 |
929 | ```lua
930 | for index = 10, 1 do
931 | print( index )
932 | end
933 | ```
934 |
935 | You should notice that there is no new output. This is because the default increment is `1`. Because the index is already past `1`, the loop does nothing. To fix this, change the increment to `-1`.
936 |
937 | Now make a while-loop that counts from 1 to 10:
938 |
939 | ```lua
940 | while counter < 10 do
941 | counter = counter + 1
942 | print( counter )
943 | end
944 | ```
945 |
946 | You should get an error that says: `attempt to compare nil with a number`. That's because you never assigned `counter`. Assign counter to `1`. Now you should get an output, but wait! The loop prints `2` first, instead of `1`. To fix this, you need to change `counter` to be `0`. Note that this happens because you increment the variable, **then** output it, so while counter *starts* at `1`, it becomes `2` before it is displayed.
947 |
948 | Now make a while-loop that counts from 10 to 1:
949 |
950 | ```lua
951 | downCounter = 10
952 | while downCounter < 1 do
953 | downCounter = downCounter + 1
954 | print( downCounter )
955 | end
956 | ```
957 |
958 | When you run this, you should get no output. That's because the initial condition is not `true`, so it never executes. Change that to be
959 |
960 | ```lua
961 | while downCounter > 1 do
962 | ```
963 |
964 | You should get an infinite loop this time. Remember to break output by pressing `Ctrl` and `c` at the same time. Can you see why you get an infinite loop? It's because the condition will never change: 10 > 1, 11 > 1, and so on. You need to change the reassignment of `downCounter` to decrement (go down by one) instead of increment (increase by one).
965 |
966 | Finally, make a repeat-until loop that counts from 1 to 10 and another that counts from 10 to 1. The first one should look something like this:
967 |
968 | ```lua
969 | repeat
970 | print( counter )
971 | counter = counter + 1
972 | until counter > 9
973 | ```
974 |
975 | You may have been expecting an error because `counter` was not defined, but instead what you got was an infinite loop. Why is that? Because you used `counter` in the first while-loop you created. So you either need to reassign `counter` or choose another variable (and assign it). Reassign the variable here, like so:
976 |
977 | ```lua
978 | counter = 0
979 | repeat
980 | print( counter )
981 | counter = counter + 1
982 | until counter > 9
983 | ```
984 |
985 | Finally, use a repeat-until loop to count from 10 to 1, using the same variable as you used for the first repeat-until loop:
986 |
987 | ```lua
988 | repeat
989 | print( counter )
990 | counter = counter - 1
991 | until counter < 1
992 | ```
993 |
994 | ***Remember*** to add *lots* of comments to the file! These are your notes!
995 |
996 |
997 |
998 |
999 |
1000 | ## If-Then Statements
1001 |
1002 | Sometimes when you are programming, you only want to do something **if** some other thing is true. For instance, you may want your while-loop to quit after it executes 100 times. You would use an **if-then** statement to do this. These follow the following structure (you should **not** run this file):
1003 |
1004 | ```lua
1005 | if ( BOOLEAN ) then
1006 | -- Code
1007 | end
1008 | ```
1009 |
1010 | For instance, you could display if a person's age is over 18:
1011 |
1012 | ```lua
1013 | age = 21
1014 |
1015 | if age > 18 then
1016 | print( 'This person is over 18' )
1017 | end
1018 | -- This person is over 18
1019 | ```
1020 |
1021 | You may have noticed by now there are several different ways to compare numbers. You've seen some of them, and may be familiar with some, but there are still several more which will be discussed below.
1022 |
1023 | ### Comparisons
1024 |
1025 | In math, there are several operators that you may be familiar with:
1026 |
1027 | - Equal to
1028 |
1029 | - Not equal to
1030 |
1031 | - Greater than
1032 |
1033 | - Less than
1034 |
1035 | - Greater than or equal to
1036 |
1037 | - Less than or equal to
1038 |
1039 | These can all be expressed in Lua as follows:
1040 |
1041 | | Mathematical expression | Lua equivalent |
1042 | |--------------------------|----------------|
1043 | | Equal to | `==` |
1044 | | Not equal to | `~=` |
1045 | | Greater than | `>` |
1046 | | Less than | `<` |
1047 | | Greater than or equal to | `>=` |
1048 | | Less than or equal to | `<=` |
1049 | | Modulo | `%` |
1050 |
1051 | You may not be familiar with some of these operators, such as modulo, but don't worry, they will be explained shortly.
1052 |
1053 | It may seem odd that "equal to" is `==`, but it actually makes sense: because `=` is for assignment, `==` is for comparison; it helps to distinguish the two.
1054 |
1055 | You have already seen some of the above operators in the [Basic Loops](#basic-loops) section. You can see the operators in-action with some examples (remember to run this on the interactive Lua command line):
1056 |
1057 | ```lua
1058 | if 3 > 2 then
1059 | print( '3 > 2' )
1060 | end
1061 |
1062 | if 3 >= 3 then
1063 | print( '3 >= 3' )
1064 | end
1065 |
1066 | if 3 ~= 2 then
1067 | print( '3 is not equal to 2' )
1068 | end
1069 | ```
1070 |
1071 | Note that all of these commands work **only** for numbers, except for `==` and `~=`, as demonstrated below:
1072 |
1073 | ```lua
1074 | str1 = 'This is a test'
1075 | str2 = 'This is a test'
1076 |
1077 | if str1 == str2 then
1078 | print( 'These are both tests' )
1079 | end
1080 |
1081 | bool1 = true
1082 | bool2 = true
1083 |
1084 | if bool1 == bool2 then
1085 | print( 'These booleans are equal' )
1086 | end
1087 | ```
1088 |
1089 | #### Modulo
1090 |
1091 | The `modulo` operator gives the remainder of a number after division. For instance, `4 % 3` is 1, because the result of `4 / 3` is 1 with a remainder of 1. You can use this in many ways. For instance, a number is even if the result of its modulo with 2 is 0.
1092 |
1093 | ```lua
1094 | number = 10
1095 | if number % 2 == 0 then
1096 | print( 'This number is even' )
1097 | end
1098 | ```
1099 |
1100 | #### The Length Operator
1101 |
1102 | There is also another operator that *cannot* be used with numbers or booleans: `#`, the **length** operator. This gives you the length, for instance, of a string, in characters. For instance:
1103 |
1104 | ```lua
1105 | test1 = 'test'
1106 | print( #test1 ) -- 4
1107 |
1108 | test2 = 'test2'
1109 | print( #test2 ) -- 5
1110 |
1111 | test3 = 'test again'
1112 | print( #test3 ) -- 10
1113 | ```
1114 |
1115 | This can have several applications. For instance, if a user's password must have a certain length, you could alert them:
1116 |
1117 | ```lua
1118 | password = 'hunter2'
1119 |
1120 | if #password < 10 then
1121 | print( 'Error: your password is not long enough!' )
1122 | end
1123 | ```
1124 |
1125 | #### Assigning Booleans
1126 |
1127 | You've seen before that you can assign booleans by giving it either a value of `true` or `false`. But a boolean can also be assigned by a value. For instance, if you wanted to represent that a comparison with a boolean, you could do:
1128 |
1129 | ```lua
1130 | age = 18
1131 |
1132 | canSmoke = age >= 18
1133 | canDrink = ( age >= 21 )
1134 |
1135 | print( 'You can smoke: ', canSmoke ) -- You can smoke: true
1136 | print( 'You can drink: ', canDrink ) -- You can smoke: false
1137 | ```
1138 |
1139 | Note that surrounding the condition in parenthesis, while not required, is recommended for clarity.
1140 |
1141 | Notice that for `canSmoke`, `age >= 18` returns `true`, because `18 >= 18`. For the `canDrink`, however, `18 >= 21` is `false`, so `canDrink` is `false`.
1142 |
1143 | This is actually how the comparison in if-then statements work, as well as the while-loops and repeat-until loops. It simply checks if the condition is equal to `true`. For instance, the following two if statements are equivalent:
1144 |
1145 | ```lua
1146 | name = 'John'
1147 |
1148 | if #name == 4 then
1149 | print( name .. ' is four letters long' )
1150 | end
1151 |
1152 | -- or
1153 |
1154 | name = 'John'
1155 |
1156 | if ( #name == 4 ) == true then
1157 | print( name .. ' is four letters long' )
1158 | end
1159 | ```
1160 |
1161 | Notice that the parenthesis in the second example are *completely* optional, though I **strongly** recommend using them for clarity's sake.
1162 |
1163 | ### Else
1164 |
1165 | But what if the comparison is **not true**? Lua includes an extension of the if-then statement. This is called **else**. If the condition is not `true`, the else branch is executed. The basic structure is (not that you should **not** run this):
1166 |
1167 | ```lua
1168 | if BOOLEAN then
1169 | -- Code
1170 | else
1171 | -- Other code
1172 | end
1173 | ```
1174 |
1175 | Here's an example:
1176 |
1177 | ```lua
1178 | if 3 > 5 then
1179 | print( 'What\'s going on?' )
1180 | else
1181 | print( 'That\'s more like it!' )
1182 | end
1183 | -- That's more like it!
1184 | ```
1185 |
1186 | ### Elseif
1187 |
1188 | Now we have cases for where the boolean is `true` and `false`. But what about when you want to make multiple comparisons? You *could* do something like this (note that you should **not** run this):
1189 |
1190 | ```lua
1191 | if firstBoolean then
1192 | -- Code
1193 | else
1194 | if secondBoolean then
1195 | -- More code
1196 | else
1197 | if thirdBoolean then
1198 | -- Even more code
1199 | else
1200 | -- Etc
1201 | end
1202 | end
1203 | end
1204 | ```
1205 |
1206 | This works, but can become unmanageable very quickly. Instead, Lua has what is called an **elseif** statement. This is for when a variable can be in multiple states, such as a string. For instance:
1207 |
1208 | ```lua
1209 | -- Run this several times, alternating `name` between 'Joe', 'Frank', and 'Bob'
1210 | name = 'Joe'
1211 |
1212 | if name == 'Joe' then
1213 | print( 'Joe is not cool enough to be a part of our club!' )
1214 | elseif name == 'Frank' then
1215 | print( 'Frank is almost cool enough to be a part of our club!' )
1216 | elseif name == 'Bob' then
1217 | print( 'Bob is definitely not cool enough to be a part of our club!' )
1218 | else
1219 | print( 'Who are you?' )
1220 | end
1221 | ```
1222 |
1223 | Note that capitalization **does** matter. `'frank'` ~= `'Frank'` and so on. You can even have if statements within if-then statements. For instance, if the length of the name is the fallback condition for joining the secret club mentioned above, you could do this:
1224 |
1225 | ```lua
1226 | name = 'Joe'
1227 |
1228 | if name == 'Joe' then
1229 | print( 'Joe is not cool enough to be a part of our club!' )
1230 | elseif name == 'Frank' then
1231 | print( 'Frank is almost cool enough to be a part of our club!' )
1232 | elseif name == 'Bob' then
1233 | print( 'Bob is definitely not cool enough to be a part of our club!' )
1234 | else
1235 | -- Only let them in if their name is longer than 6 letters
1236 | nameLength = #name
1237 | if nameLength > 6 then
1238 | print( 'You\'re in, ' .. name .. '!' )
1239 | elseif nameLength >= 5 then
1240 | print( 'You\'re almost cool enough, ' .. name .. '.' )
1241 | else
1242 | print( 'Sorry, you\'re not cool enough, ' .. name .. '.' )
1243 | end
1244 | end
1245 | ```
1246 |
1247 | Notice the first `elseif` statement: the first condition (`if nameLength > 6`) is only `true` if the number is greater than 6, which does **not** include 6. The next statement (`elseif nameLength >= 5`) will *only* trigger if `nameLength` is 5 or 6 letters long.
1248 |
1249 | ### Boolean Operators
1250 |
1251 | Sometimes you would like to do the same thing if two conditions are met. You **could** do this:
1252 |
1253 | ```lua
1254 | if cond1 then
1255 | -- Code
1256 | elseif cond2 then
1257 | -- Exact same code
1258 | else
1259 | -- Etc
1260 | end
1261 | ```
1262 |
1263 | Other times you would like to only execute code if more than one condition is met. You **could** do this:
1264 |
1265 | ```lua
1266 | if cond1 then
1267 | if cond2 then
1268 | if cond3 then
1269 | -- Code
1270 | end
1271 | end
1272 | end
1273 | ```
1274 |
1275 | Of course, as I'm sure you're probably thinking by now, there are *much* better alternatives. Both of the above *work*, but are not flexible enough to be real solutions. Instead, there are two **boolean operators**: **or** and **and**.
1276 |
1277 | #### Or
1278 |
1279 | Or works just like you'd expect it to: It returns true if *either* of the conditions are `true`. For instance:
1280 |
1281 | ```lua
1282 | print( ( 3 > 1 ) or ( 3 > 5 ) ) -- True
1283 | print( ( 3 > 1 ) or ( 3 < 5 ) ) -- True
1284 | print( ( 3 < 1 ) or ( 3 < 5 ) ) -- True
1285 | print( ( 3 < 1 ) or ( 3 > 5 ) ) -- False
1286 | ```
1287 |
1288 | This can be utilized within the boolean condition for while loops *or* if-then statements (see what I did there?):
1289 |
1290 | ```lua
1291 | iterations = 0
1292 | condition = false
1293 |
1294 | while ( iterations <= 100 ) or ( condition ) do
1295 | condition = false
1296 | iterations = iterations + 1
1297 | print( 'Still looping!' )
1298 | end
1299 |
1300 | print( 'Done looping!' )
1301 | ```
1302 |
1303 | ```lua
1304 | name = 'Blake'
1305 |
1306 | if name == 'John' or #name == 5 then
1307 | print( 'Hiya, ' .. name )
1308 | else
1309 | print( 'Who are you?' )
1310 | end
1311 | ```
1312 |
1313 | #### And
1314 |
1315 | While `or` is used for *either* condition, `and` is used for *both* conditions. For example:
1316 |
1317 | ```lua
1318 | superCool = true
1319 | superSmart = true
1320 |
1321 | if superCool and superSmart then
1322 | print( 'I am super cool and super smart' )
1323 | elseif superCool or superSmart then
1324 | print( 'One out of two \'aint bad!' )
1325 | else
1326 | print( 'At least I have my personality!' )
1327 | end
1328 | ```
1329 |
1330 | Try changing around the booleans in the above example to see how that affects the execution of the code.
1331 |
1332 | #### Not
1333 |
1334 | While `and` and `or` work with two conditions, `not` works with only one. It **negates** the operation. Essentially what it does is swap the boolean. For instance:
1335 |
1336 | ```lua
1337 | cool = true
1338 | notCool = not cool
1339 |
1340 | print( cool ) -- true
1341 | print( notCool ) -- false
1342 | ```
1343 |
1344 | But `not` can be used on more than just booleans. In Lua, anything that is not `false` or `nil` is `true`, so `not` would make those statements `false`:
1345 |
1346 | ```lua
1347 | print( not true ) -- false
1348 | print( not 100 ) -- false
1349 | print( not 'My name is John' ) -- false
1350 |
1351 | print( not false ) -- true
1352 | print( not nil ) -- true
1353 | ```
1354 |
1355 | You can get the "truthiness" of a value by negating it *twice*. For instance, you know that a string is "truthy", because
1356 |
1357 | ```lua
1358 | print( not not 'This is truthy' ) -- true
1359 | ```
1360 |
1361 | This is because `not true` is `false`, so `not not true` is the same as `not false`, which is `true`.
1362 |
1363 | Because `nil` is `false`, you have to be careful when you're doing if statements, otherwise a `nil` variable can have unexpected results:
1364 |
1365 | ```lua
1366 | superCool = true
1367 |
1368 | if SuperCool then
1369 | print( 'I am super cool!' )
1370 | else
1371 | print( 'Why am I not cool? :(' )
1372 | end
1373 | ```
1374 |
1375 | Note that, because `SuperCool` is not defined, it evaluates to `nil`, causing the statement to be `false`.
1376 |
1377 | ### Using If-Statements with Break
1378 |
1379 | If you recall from the previous section, you learned about the `break` command. Recall also that, with `if-then` statements, if `BOOLEAN` is `true`, the code executes. Otherwise, nothing happens. So if you wanted to `break` a `while-loop` after 100 executions, you would do something like this:
1380 |
1381 | ```lua
1382 | numberOfTimes = 1
1383 | booleanThatWontChange = true
1384 |
1385 | while booleanThatWontChange do
1386 | numberOfTimes = numberOfTimes + 1
1387 | print( numberOfTimes )
1388 | if numberOfTimes > 99 then
1389 | print( 'That loop went on way too long!' )
1390 | break
1391 | end
1392 | end
1393 | ```
1394 |
1395 | ### Exercises
1396 |
1397 | Create a file called `03 Conditionals.lua`. Within it, create an if-elseif-else statement that determines if a person can join your super secret club. The criteria are:
1398 |
1399 | - If they're a guy:
1400 |
1401 | - They have to be over 21
1402 |
1403 | - Their name cannot be over 7 letters long
1404 |
1405 | - If they're a girl:
1406 |
1407 | - They have to be over 18 and under 30
1408 |
1409 | You need specific reasoning as to why they were denied admission to the club as well.
1410 |
1411 | There are several ways that you could implement this. See if you can figure it out yourself first, before looking at the solution below:
1412 |
1413 | ```lua
1414 | name = 'John'
1415 | age = 23
1416 | male = true
1417 |
1418 | if male then
1419 | -- Male
1420 | if age >= 21 then
1421 | if #name <= 7 then
1422 | print( 'You\'re in, ' .. name .. '!' )
1423 | print( 'First round\'s on you!' )
1424 | else
1425 | print( 'Sorry, you\'re name is way too long' )
1426 | print( 'Not enough room on our name tags' )
1427 | end
1428 | else
1429 | print( 'Sorry, you\'ll need to come back when you\'re older' )
1430 | end
1431 | else
1432 | -- Female
1433 | if age >= 18 then
1434 | if age <= 30 then
1435 | print( 'Come on in, ' .. name )
1436 | else
1437 | print( 'Sorry, you\'re way too old!' )
1438 | print( 'There\'s a retirement home across the street' )
1439 | end
1440 | else
1441 | print( 'You\'re not old enough!' )
1442 | end
1443 | ```
1444 |
1445 | When you run the file, if you've typed it **exactly** as I have, you should get the error `lua: 03 Conditionals.lua:29: 'end' expected (to close 'if' at line 1) near .` This error may seem confusing at first, but after inspection it is a little more clear: `` if just a fancy way to represent the **e**nd **o**f **f**ile. That's because you're missing the `end` to close the `-- Female` if-statement.
1446 |
1447 | Of course, this is not the **only** implementation you can use. As with any problem, there can be multiple solutions to one problem.
1448 |
1449 | Now say you want to do some error checking to make sure you don't get any errors if the user accidentally assigns the value incorrectly. Remember the [`type`](#the-type-command) command? You can use this with an if-statement to validate the input:
1450 |
1451 | ```lua
1452 | name = 123
1453 | age = '23'
1454 | male = nil
1455 |
1456 | if type( name ) ~= 'string' then
1457 | print( 'Invalid input: name must be a string' )
1458 | elseif type( age ) ~= 'number' then
1459 | print( 'Invalid input: age must be a number' )
1460 | elseif type( male ) ~= 'boolean' then
1461 | print( 'Invalid input: male must be a boolean' )
1462 | else
1463 | if male then
1464 | -- Male
1465 | if age >= 21 then
1466 | if #name <= 7 then
1467 | print( 'You\'re in, ' .. name .. '!' )
1468 | print( 'First round\'s on you!' )
1469 | else
1470 | print( 'Sorry, you\'re name is way too long' )
1471 | print( 'Not enough room on our name tags' )
1472 | end
1473 | else
1474 | print( 'Sorry, you\'ll need to come back when you\'re older' )
1475 | end
1476 | else
1477 | -- Female
1478 | if age >= 18 then
1479 | if age <= 30 then
1480 | print( 'Come on in, ' .. name )
1481 | else
1482 | print( 'Sorry, you\'re way too old!' )
1483 | print( 'There\'s a retirement home across the street' )
1484 | end
1485 | else
1486 | print( 'You\'re not old enough!' )
1487 | end
1488 | end
1489 | ```
1490 |
1491 | Now let's add another example. Say that you want to determine if a number is prime. A number is prime if:
1492 |
1493 | 1. The number is only divisible by one and itself
1494 |
1495 | 1. The number is an integer
1496 |
1497 | First, let's test if a number is an integer. There are many ways to do this. Recall from earlier, the [modulo](#modulo) operator gives the remainder of division. This may not seem to have any application, but this can be very useful: if a number is divisible by one it's an integer. So, for our prime number checker, let's start by making sure that number is an integer:
1498 |
1499 | ```lua
1500 | -- Number to check if it's prime
1501 | number = 3
1502 |
1503 | -- Ensure number is an integer
1504 | if number % 1 == 0 then
1505 | print( 'The number is prime so far!' )
1506 | else
1507 | print( 'The number is not an integer, so it\'s not prime' )
1508 | end
1509 | ```
1510 |
1511 | Change `number` from `3` to `3.1` to see how the results change.
1512 |
1513 | Now let's add a check to see if the number is divisible by any other numbers. This can be done with a for loop:
1514 |
1515 | ```lua
1516 | -- Number to check if it's prime
1517 | number = 3
1518 |
1519 | -- Ensure number is an integer
1520 | if number % 1 == 0 then
1521 | -- Check if a number is divisible by any other numbers
1522 | for i = 2, number - 1 do
1523 | if number % i == 0 then
1524 | -- Number is divisible by another number
1525 | print( 'This number is divisible by ', i, 'so it is not prime' )
1526 | else
1527 | print( 'This number is prime!' )
1528 | end
1529 | end
1530 | else
1531 | print( 'The number is not an integer, so it\'s not prime' )
1532 | end
1533 | ```
1534 |
1535 | Your output should be `This number is prime!`. It appears that everything is working correctly. But change `number` to a prime number other than `3`, such as `5`, and your output will not be what you expected. You should see that it prints `This number is prime!` 3 times! This makes sense if you walk through the for-loop:
1536 |
1537 | ```
1538 | number = 5
1539 |
1540 | for i = 2, 4 do
1541 | i = 2:
1542 | Is 5 divisible by 2? No, so:
1543 | This number is prime!
1544 | i = 3
1545 | Is 5 divisible by 3? No, so:
1546 | This number is prime!
1547 | i = 4
1548 | Is 5 divisible by 4? No, so:
1549 | This number is prime!
1550 | ```
1551 |
1552 | As you can see what we need is some way to determine if the `if-then` statement is `true` for **all** executions of the `for-loop`. We can use a boolean to represent this:
1553 |
1554 | ```lua
1555 | -- Number to check if it's prime
1556 | number = 3
1557 |
1558 | -- Ensure number is an integer
1559 | if number % 1 == 0 then
1560 | -- Shows whether number is divisible by any other numbers or not
1561 | isDivisible = false
1562 |
1563 | -- Check if a number is divisible by any other numbers
1564 | for i = 2, number - 1 do
1565 | if number % i == 0 then
1566 | -- Number is divisible by another number
1567 | print( 'This number is divisible by ', i, 'so it is not prime' )
1568 |
1569 | -- number is divisible by another number, so set isDivisible to true
1570 | isDivisible = true
1571 | end
1572 | end
1573 |
1574 | -- After the loop is done, check if isDivisible is false
1575 | if not isDivisible then
1576 | print( 'Our number is prime!' )
1577 | end
1578 | else
1579 | print( 'The number is not an integer, so it\'s not prime' )
1580 | end
1581 | ```
1582 |
1583 | A keen observer would note that you could even thrown in a `break` statement at the end of the divisibility check, as only one number needs to fail for `isDivisible` to become `true`. Now the code works for *most* cases. But what about negative numbers? Negative numbers are not prime, since the are all divisible by at *least* `1`, `-1`, and themselves. Plus, zero and one are not prime numbers either, so we will need to check for these as well:
1584 |
1585 | ```diff
1586 | -- Number to check if it's prime
1587 | number = 3
1588 |
1589 | -- Ensure number is an integer
1590 | if number <= 1 then
1591 | print( 'This number is not prime: prime numbers must be > 1' )
1592 | elseif number % 1 == 0 then
1593 | -- Shows whether number is divisible by any other numbers or not
1594 | isDivisible = false
1595 |
1596 | -- Check if a number is divisible by any other numbers
1597 | for i = 2, number - 1 do
1598 | if number % i == 0 then
1599 | -- Number is divisible by another number
1600 | print( 'This number is divisible by ', i, 'so it is not prime' )
1601 |
1602 | -- number is divisible by another number, so set isDivisible to true
1603 | isDivisible = true
1604 | end
1605 | end
1606 |
1607 | -- After the loop is done, check if isDivisible is false
1608 | if not isDivisible then
1609 | print( 'Our number is prime!' )
1610 | end
1611 | +else
1612 | - print( 'The number is not an integer, so it\'s not prime' )
1613 | end
1614 | ```
1615 |
--------------------------------------------------------------------------------
/LuaGuideFormatted.md:
--------------------------------------------------------------------------------
1 | # An Introduction to Lua
2 |
3 | ## Introduction
4 |
5 | Learning how to program is a very rewarding experience. Whether you're
6 | learning for school, your career, or just for fun, programming is a
7 | useful skill and does not need to be hard or complicated.
8 |
9 | ### Purpose
10 |
11 | The purpose of this guide is to take a person who knows little to nothing
12 | about programming and to teach them Lua (version 5.2, though all versions
13 | numbered with a '5' as the first number should be very similar). By the
14 | end of the tutorial, the reader should be able to read and write Lua
15 | with general ease.
16 |
17 | ### Why Lua?
18 |
19 | You may be wondering: "Why should I learn Lua?" There are several features
20 | of Lua that make it ideal as a first language:
21 |
22 | - Lua is a small language. This means that it has very few built-in
23 | commands. While this may not seem like an advantage at first, there are
24 | a few reasons why this is beneficial:
25 |
26 | - It makes the language easier to learn.
27 |
28 | - It reinforces concepts. Because many aspects that other
29 | languages have are not present by default in Lua, you gain a
30 | better understanding of how the concept works by implementing
31 | it yourself.
32 |
33 | - The main thing to keep in mind when programming is that computers are
34 | very literal. You have to tell the computer step-by-step what exactly you
35 | want it to do and how to do it. How much detail you include depends on
36 | the language you're using: Lua is good because it allows you to program
37 | without dealing with unnecessary complications for beginners like "memory
38 | allocation" and things like that. While these are useful for more advanced
39 | programmers, for beginners, these tend to be complicated and confusing.
40 |
41 | - Lua is more forgiving than many languages. Many languages
42 | feature complex and confusing processes, such as "static typing" and
43 | "compiling." These can be confusing for first-time users. Because Lua does
44 | not feature concepts like these, there will be at no point a concept where
45 | the reader is told to "Just trust me" (though I will delay explaining
46 | some topics fully until later in order to avoid confusion). Throughout
47 | this tutorial I will make an effort to explain not only how, but also
48 | why things are the way they are.
49 |
50 | - Installing Lua is very simple and straightforward.
51 |
52 | ### Thinking Like a Computer
53 |
54 | Earlier, I mentioned that, when programming, you need to tell the computer
55 | what to do with step-by-step instructions. This can be difficult for
56 | people to get used to at first; they expect the computer to "know what
57 | they mean," which rarely happens. Think of a computer as a very literal
58 | person who does **exactly** what you tell them to. For instance, most
59 | people would be able to follow these instructions and understand what
60 | is going on:
61 |
62 | 1. Set the toaster to the desired setting
63 |
64 | 1. Put in bread as desired
65 |
66 | 1. Retrieve the toast when it is ready
67 |
68 | 1. Butter to taste
69 |
70 | Anybody can read this and know that you are making toast, and will
71 | be able to follow this recipe without difficulty. If you told a very
72 | literal robot chef to do this, however, you would run into a few
73 | problems. First of all, you never told the robot chef to retrieve the
74 | bread initially. Additionally, it probably has no idea what "as desired",
75 | "to taste", or similarly vague phrases mean.
76 |
77 | When programming, you need to understand that the computer does *not*
78 | know what you are trying to do, nor does it care. It will do exactly
79 | what you tell it to do; nothing more, nothing less.
80 |
81 | ### Installing and Setting up an Editor
82 |
83 | In order to edit code, you need something called a **text editor**. An
84 | editor is what you use to write your code. Editors can be as simple or
85 | complex as you would like them to be. You can even use Notepad to edit
86 | your Lua files, though I would **strongly** advise against this for
87 | several reasons. Primarily, it lacks syntax highlighting, which makes
88 | your code easier to read. It also lacks an advanced undo structure,
89 | which severely limits your ease-of-use. For most entry-level users, I
90 | recommend installing ZeroBrane, an **IDE**, or **Integrated Development
91 | Environment** for Lua. What does "integrated development environment"
92 | mean? Basically, it makes programming in Lua easier by aiding in some
93 | common tasks. One big advantage is that it comes installed with several
94 | versions of Lua and is very easy to install. The installation process
95 | is as follows:
96 |
97 |
99 |
100 | 1. Go to [studio.zerobrane.com](https://studio.zerobrane.com)
101 |
102 | 1. Select the "Download" tab on the right side of the page
103 |
104 |
107 |
108 | 1. Select the option "*Take me to the download page this time*" for now
109 | (unless you're feeling generous). This program is available for free,
110 | but you can fund the development now (or at a later date) if you desire.
111 |
112 |
114 |
115 | 1. Select "*Windows 32bit (exe installer)*" (assuming that you are on
116 | Windows, of course!)
117 |
118 |
119 |
122 |
123 | 1. If you get the option to choose where the installer is downloaded,
124 | put it in your "*Downloads*" directory
125 |
126 | 1. Once you've selected the directory, click "Save" (*You may not see
127 | these steps if you have not configured your internet browser to allow
128 | you to choose where your downlaods go*)
129 |
130 |
133 |
134 | 1. Now you need to figure out if your computer is 32 or 64 bits. If
135 | you're not sure, open the File Explorer and go to "C:\\". This will be
136 | found either under "This PC" or "My Computer" depending on the age of
137 | your computer. If you have a directory called "Program Files (x86)",
138 | as pictured here, you are using a 64 bit computer; if not, you're using
139 | a 32 bit computer.
140 |
141 |
144 |
145 | 1. Now, run the installer. This can be done by navigating to the directory
146 | where it was downloaded and double-clicking the installer. It should
147 | be called something like "*ZeroBraneStudioEduPack-1.60-win32.exe*". If
148 | you were not able to choose where the download goes, look in your
149 | "*Downloads*" folder or see if your internet browser will display the
150 | location where it was downloaded.
151 |
152 |
155 |
156 | 1. When you run the installer, you should be greeted by this pop-up
157 | dialog box. If you can't read the text, try holding `Ctrl` and moving
158 | your mouse wheel. Select the text under the heading "*Destination folder*"
159 | so that it appears blue, like pictured above.
160 |
161 |
164 |
165 | 1. Now you need to choose where the program should be installed. For 64
166 | bit systems, install the program in "*C:\\Program Files (x86)\\ZeroBrane*"
167 | and for 32 bit systems, install the program in "*C:\\Program
168 | Files\\ZeroBrane*". Note that the location does not matter that much;
169 | it's just good practice to put files in these locations so that they
170 | are easier to find later on. While installing, you will probably be
171 | asked to grant administrator privileges. Allow the program to run with
172 | administrator privileges in order to install successfully.
173 |
174 |
177 |
178 | 1. Once the installation is completed, you should be greeted with a screen
179 | that looks like this. Congratulations! Your installation is complete.
180 |
181 |
184 |
185 | 1. Next you will want to create a shortcut on your desktop so that it
186 | is easier to run the program. To do this, close or minimize all open
187 | windows and right-click on the desktop (**not** one of the icons). Move
188 | the mouse down until you see the "*New*" option.
189 |
190 | 1. From the new menu, choose the option "*Shortcut*" to create a shortcut
191 | on your desktop.
192 |
193 |
196 |
197 | 1. You should be greeted with a prompt that looks something like the
198 | above. Select "*Browse*" to locate the program.
199 |
200 |
203 |
204 | 1. Navigate to the location of the ZeroBrane Studio executable. If
205 | you followed the steps above, it should be in "*C:\\Program Files
206 | (x86)\\ZeroBrane\\*" or "*C:\\Program Files\\ZeroBrane\\*". Select the
207 | executable called `zbstudio`. (*Note that the "C:\\" directory is located
208 | in either "This PC" or "My Computer" depending on the age of your system*)
209 |
210 | 1. Once you have selected the executable, select "*OK*" to continue.
211 |
212 |
215 |
216 | 1. Once the program has been selected, its path should appear, like
217 | so. Choose "*Next*" to continue.
218 |
219 |
222 |
223 | 1. Give a name to the program. The name does not matter, so you can
224 | change the name if you want. Just make sure that it makes sense. For
225 | instance, you could change the name from "*zbstudio*" to "*ZeroBrane*"
226 | if you wanted. When you're done, click "*Finish*."
227 |
228 |
230 |
231 | 1. Now you should have a shortcut on your desktop, as you see here. If
232 | you double-click this icon you will launch ZeroBrane studio, bringing
233 | you to the same screen that you saw before.
234 |
235 | ### Format of this Guide
236 |
237 | This guide is broken into several logical sections. In order to keep
238 | yourself organized, and make it easier to review your notes, I recommend
239 | making a folder on your desktop that will contain several folders
240 | within it.
241 |
242 | #### Creating a Directory for This Guide
243 |
244 | Creating a directory is simple and easy to do, as demonstrated below:
245 |
246 |
248 |
249 | 1. Close or minimize all open windows and right-click on your desktop
250 | (**not** on an icon).
251 |
252 | 1. Move your mouse over to the "*New*" option.
253 |
254 | 1. Select the option "*Folder*".
255 |
256 |
258 |
259 | 1. Now you should have a new folder created on your desktop, as pictured
260 | above.
261 |
262 |
265 |
266 | 1. Give the folder a name that will help you identify it later, like
267 | "*Lua*" or something like that.
268 |
269 | Now you should be ready to keep all of your files organized in one place.
270 |
271 | #### Changing the Interpreter
272 |
273 | At the beginning of the guide, I said that the version of Lua that you'll
274 | be learning is Lua 5.2. While the versions are all fairly similar, some
275 | minor discrepancies exist from version to version. In order to keep any
276 | of these discrepancies from occurring, the interpreter will need to be
277 | changed in order to reflect this. The **interpreter** is what runs the
278 | Lua scripts that you write. It converts your code into something that
279 | the computer can understand and use. Changing the interpreter is very
280 | easy to do, as can be seen below:
281 |
282 |
283 |
284 |
285 | 1. Open up ZeroBrane and move your mouse to the "*Project*" heading.
286 |
287 | 1. Move your mouse down to the "*Lua Interpreter*" section.
288 |
289 | 1. Select the version "*Lua 5.2*".
290 |
291 | Now your program will be run using the Lua 5.2 interpreter.
292 |
293 | #### Running the Console
294 |
295 | Each sections in this guide is composed of two parts: **Instruction**
296 | and **Exercises**. In the instruction section, commands are entered
297 | through ZeroBrane's interactive console. In the exercises section,
298 | a file is created and run.
299 |
300 | The interactive console can be run like so:
301 |
302 |
304 |
305 | 1. At the bottom of ZeroBrane's window, you should see three tabs,
306 | as pictured above.
307 |
308 |
310 |
311 | 1. Move your mouse over to the one labeled "Local console" and select
312 | it. You should now see the above text telling you that you are working
313 | with the interactive Lua interpreter, also known as the console.
314 |
315 | #### Creating a New File
316 |
317 | In the exercises section, the entire file is executed all at once. You
318 | can create these files using ZeroBrane, as demonstrated below:
319 |
320 |
322 |
323 |
324 | 1. At the top of the ZeroBrane window, move your mouse over to "*File*".
325 |
326 | 1. Select the option "*New*".
327 |
328 |
330 |
331 | 1. You should now have a new tab open up next to the "*Welcome*" tab,
332 | like so.
333 |
334 |
336 |
337 | 1. With the file you want to save selected, go to the "*File*" heading.
338 |
339 | 1. Select the "*Save*" option. The first time that you save the file,
340 | you should get a pop-up dialog asking you where you would like to save
341 | it, as shown below.
342 |
343 |
345 |
346 | 1. You will want to keep all of your files located in logical places so
347 | that they are easier to find, such as the folder you made earlier. For
348 | this tutorial, I recommend saving all of your files in a folder on your
349 | desktop. To do this, select the "*Desktop*" option on the side of the
350 | file explorer, as pictured above. If you do not see this option, you
351 | will have to go to "*C:\\Users\\YOURNAME\\Desktop\\*", where *YOURNAME*
352 | is your username on your computer.
353 |
354 |
356 |
357 | 1. To select the folder that you created earlier, either double-click
358 | the folder or select the folder then click "*Open*".
359 |
360 |
362 |
363 | 1. Give the file a name by clicking in the box labeled "*File name:*"
364 | and giving it a name that you desire, then clicking "*Save*". Here,
365 | I have named my program "*test.lua*".
366 |
367 | Once you have created the file, it can be run using the IDE, as
368 | demonstrated below.
369 |
370 | #### Running the File
371 |
372 | In the exercises code sections, files are run. Running a file is simple
373 | and will comprise the majority of what you do when you're programming.
374 |
375 |
377 |
378 | 1. Create a new blank file, as demonstrated in the section [Creating a
379 | New File](#creating-a-new-file).
380 |
381 | 1. Move your mouse over to the "*Project*" heading
382 |
383 | 1. Select the first option, "*Run*".
384 |
385 |
387 |
388 | 1. You should see the text below when you run a file. Each line contains
389 | information about your program:
390 |
391 | 1. The first line tells you initial settings and information:
392 |
393 | 1. The location of the Lua interpeter that you are using
394 | (`"C:\Program Files (x86)\ZeroBrane\bin\lua52.exe"`).
395 |
396 | 1. The `-e io.stdout:setvbuf('no')"` is a command that
397 | is executed before the code is run. Basically, it makes
398 | viewing the output easier.
399 |
400 | 1. The location of the file being run
401 | (`"C:\Users\User\Desktop\Lua\test.lua"`).
402 |
403 | 1. The second line tells you information about the "*project*",
404 | which is how ZeroBrane groups Lua files:
405 |
406 | 1. `lua52.exe` is the name of the interpreter. This
407 | shows that it was started and its directory.
408 |
409 | 1. The directory `"C:\Program Files
410 | (x86)\ZeroBrane\myprograms"` refers to the *directory*
411 | of the Lua file. The directory allows you to use multiple
412 | files together at once.
413 |
414 | 1. The third line tells you about the details from the script
415 | execution:
416 |
417 | 1. It ran in `0.05` seconds.
418 |
419 | 1. Its **PID**, or Process Identification Number, is 8600.
420 | This number is used by ZeroBrane to keep track of your
421 | script while its running and this PID will be different
422 | for every script invocation.
423 |
424 |
425 | ## Variables
426 |
427 | Variables contain values. These values can be of several types: `strings`,
428 | `numbers`, `booleans` and more. The type of a variable represents how it
429 | can be used and what it is used for. Variables are the building blocks
430 | of all good code and are an extremely important concept to understand.
431 |
432 | ### Variable Names and Comments
433 |
434 | Variables in Lua can be any series of letter or numbers, as long as
435 | they don't start with a number (the reasoning for this will be given
436 | later). Variables can also contain underscores, but no other special
437 | characters. This is because most of these characters are operators, such
438 | as addition or subtraction. The following are all *valid* variable names
439 | (note that you should **not** run the following in the interpreter):
440 |
441 | ```lua
442 | variable
443 | name123
444 | this_name
445 | luaIsAwesome
446 | ```
447 |
448 | The following are all **not** valid variable names (you should **not**
449 | run this section either):
450 |
451 | ```lua
452 | 2songName -- Variables cannot start with numbers
453 | this variable -- Variables cannot have spaces
454 | lua-is-awesome -- Variables can only have underscores, letters, and numbers
455 | ```
456 |
457 | You may have noticed the "`--`" above. These are called **single-line**
458 | or **one-line comments**. Anything after these two dashes is ignored by
459 | the interpreter. Comments can be used to document your code. The space
460 | after `--` does not have to be present, though I prefer the way it looks
461 | with it.
462 |
463 | You can also do **multi-line** or **block comments**, which are like
464 | comments, but span multiple lines. They are opened with "`--[[`" and
465 | closed with "`]]`". Note that with multi-line comments, there must be
466 | **no** space between `--` and `[[`. You can use multi-line comments, for
467 | example, to make notes about valid variable names. Open up the command
468 | line and type `lua` to go into interactive mode and type the following:
469 |
470 | ```lua
471 | --[[
472 | Valid variable names:
473 | ---------------------
474 | variable
475 | name123
476 | this_name
477 | luaIsAwesome
478 |
479 | Invalid variable names:
480 | -----------------------
481 | 2songName -- Variables cannot start with numbers
482 | this variable -- Variables cannot have spaces
483 | lua-is-awesome -- Variables can only have underscores, letters, and numbers
484 | ]]
485 | ```
486 |
487 | Notice how nothing happens when you finish. That is because you aren't
488 | doing anything yet. Remember, comments are ignored by the interpreter,
489 | so this is essentially the same as just hitting enter.
490 |
491 | In the above examples, you may have noticed that there are many ways to
492 | format variable names. There are two prevailing ways to separate words:
493 |
494 | ```lua
495 | variableNamesLikeThis
496 |
497 | -- or
498 |
499 | variable_names_like_this
500 | ```
501 |
502 | The first is called `camelCase` and the second is called `snake_case`. In
503 | this tutorial I will use camel case simply because I prefer it, though
504 | both methods are perfectly valid.
505 |
506 | Note that capitalization **does** matter: `thisVariable` is different from
507 | `THISVARIABLE` and so on.
508 |
509 | Variable names should be short but descriptive. The descriptive part is of
510 | more importance than the short part, however. Your variable name needs to
511 | be descriptive to help you remember the purpose of the variable. When in
512 | doubt, go with verboseness over conciseness. This will save you headaches
513 | in the long run, by keeping you from having to search all over the place
514 | for what your variable represents.
515 |
516 | ### Assigning and Accessing Variables
517 |
518 | You **assign** variables with an equal sign. Assigning a variable just
519 | means that you are giving the variable a value. Variable assignment
520 | looks like this:
521 |
522 | ```lua
523 | variableName = value
524 | ```
525 |
526 | **Accessing** variables is done by referencing the name of the
527 | variable. For instance, if you wanted to view the value of a variable,
528 | you would do so like so (enter this into the Lua command line):
529 |
530 | ```lua
531 | variableName = 5
532 | print( variableName ) -- 5 (You do not need to write comments)
533 | ```
534 |
535 | The `print` command is used to show the output of values and is part of
536 | Lua's **standard library**. It is called a **function**. A function is
537 | something that will be explained more later, but essentially it is used
538 | to make programming easier.
539 |
540 | ### Variable Types
541 |
542 | In (virtually) all programming languages, variables have what are called
543 | "types." The type of a variable dictates what the variable is used
544 | for. There are several types of variables, but the most common are
545 | `numbers` `strings`, and `booleans`.
546 |
547 | #### Numbers
548 |
549 | In the above example, `variableName` must conform to the
550 | variable naming specifications (see [Variable Names and
551 | Comments](#variable-names-and-comments) for more) and `value` can be
552 | virtually anything. For instance, if you wanted to assign a variable to
553 | the value of pi, you could do:
554 |
555 | ```lua
556 | pi = 3.14
557 | print( pi ) -- 3.14
558 | ```
559 |
560 | In this example, the variable assigned is a **number**. As mentioned
561 | before, there are many types of values a variable can store, and each
562 | type has different uses. Numbers, for instance, are used for mathematical
563 | operations.
564 |
565 | Numbers can be stored in many different formats. For instance, if you
566 | wanted to represent a number in scientific notation, you could do the
567 | following:
568 |
569 | ```lua
570 | speedOfLight = 3e8
571 |
572 | -- or
573 |
574 | speedOfLight = 3E8
575 |
576 | print( speedOfLight ) -- 300000000
577 | ```
578 |
579 | Numbers can also be stored in hexadecimal with the following notation:
580 |
581 | ```lua
582 | fourteen = 0xE
583 | fourteen = 0XE
584 | print( fourteen ) -- 14
585 | ```
586 |
587 | Note that hex numbers **must** be preceded with `0x` or `0X`. This is
588 | the representation used to store hexadecimal numbers, as well as part of
589 | the reason that variable names in Lua cannot be started with numbers,
590 | as there would be ambiguity as to whether you are referencing a number
591 | or assigning a variable.
592 |
593 | You can also perform operations and store those values as numbers. For
594 | instance:
595 |
596 | ```lua
597 | pi = 3.14
598 | r = 1
599 | area = pi * r ^ 2
600 | print( area ) -- 3.14
601 | ```
602 |
603 | Note that numbers are evaluated in the same way that you follow order
604 | of operations, though parenthesis can be used for clarity if desired.
605 |
606 | You can also use a variable in its own assignment if it already has a
607 | value. For instance, increasing a number by one is called **incrementing**
608 | and decreasing a variable by one is called **decrementing**. This is
609 | done like so:
610 |
611 | ```lua
612 | numberOfSongs = 3
613 |
614 | -- Later, say when a song is added:
615 | numberOfSongs = numberOfSongs + 1
616 | print( numberOfSongs ) -- 4
617 | ```
618 |
619 | #### Strings
620 |
621 | The `string` type is used to store characters. They're called `strings`
622 | because they contain a "string," or series of characters. The name
623 | is somewhat confusing, but their usage isn't. They're used to store
624 | virtually any information that won't be used as a number or in
625 | mathematical operations. Strings are surrounded by single quotes or
626 | double quotes. The following are all strings:
627 |
628 | ```lua
629 | state = "North Carolina"
630 | country = 'United States of America'
631 |
632 | print( state ) -- North Carolina
633 | print( country ) -- United States of America
634 | ```
635 |
636 | Note that you must open and close the string with the same type of
637 | quote. Both formats are valid, though I prefer to use single quotes
638 | because they're easier to type, so that is what I will use throughout
639 | the tutorial.
640 |
641 | It is possible to mix single and double quotes, like so:
642 |
643 | ```lua
644 | sentence = 'She said "No way Jose!"'
645 | response = "I said \"Yes way Jose!\""
646 |
647 | print( sentence ) -- She said "No way Jose!"
648 | print( response ) -- I said "Yes way Jose!"
649 | ```
650 |
651 | Note the `\"` in the second example. This is called "escaping" and
652 | is used to contain double quotes in a string surrounded by double
653 | quotes. Basically, what these do is tell Lua that these quotes are part
654 | of the string and do not represent the end of the string. Note that,
655 | because we used single quotes in the first example, there was no need
656 | to escape the double quotes (though escaping the double quotes there
657 | wouldn't be wrong). Single quotes can also be escaped.
658 |
659 | Just as there are operators you can do on numbers, there are operators you
660 | can use on strings. You can combine strings with the "`..`" operator. This
661 | is called **concatenating** strings. You can concatenate multiple strings
662 | at once.
663 |
664 | ```lua
665 | part1 = 'this'
666 | part2 = 'is'
667 | part3 = 'a'
668 | part4 = 'test'
669 |
670 | sentence = part1 .. ' ' .. part2 .. ' ' .. part3 .. ' ' .. part4
671 | print( sentence ) -- this is a test
672 | ```
673 |
674 | Note that strings can be concatenated even if they are not already
675 | assigned to a variable, as shown in the above demonstration, where the
676 | variables have already been assigned while the spaces (`' '`) have not.
677 |
678 | #### Multi-Line Strings
679 |
680 | Just as comments can be multiple lines, strings can also be multiple
681 | lines. The syntax for multi-line strings is very similar to multi-line
682 | comments. Recall that multi-line comments look like so:
683 |
684 | ```lua
685 | --[[
686 | This is a
687 | multi-line comment
688 | ]]
689 | ```
690 |
691 | This is what multi-line strings look like:
692 |
693 | ```lua
694 | mutliLineString = [[
695 | This text is part of
696 | a multi-line string.
697 |
698 | You can use both "double"
699 | and 'single quotes'
700 | without worrying
701 | ]]
702 |
703 | print( multiLineString )
704 | ```
705 |
706 | Note that the line after `without worrying` **is** present. To get rid
707 | of this extra line, simply put the `]]` on the same line as `without
708 | worrying`. Also note that the first line after `[[` is ignored.
709 |
710 | #### Booleans
711 |
712 | If numbers store numbers and strings store strings of characters,
713 | what do booleans store? Booleans store values that represent
714 | "thruthiness." Booeleans have two values: `true` or `false`.
715 |
716 | ```lua
717 | luaMaster = false
718 | luaLearner = true
719 |
720 | print( luaMaster ) -- false
721 | print( luaLearner ) -- true
722 | ```
723 |
724 | Booleans are useful when dealing in absolutes. For instance, if you
725 | had a variable `carIsRunning`, you would probably use a boolean to
726 | represent if the car is running or not, because the car can either be
727 | on or off. A car cannot be between running and not running; that's not
728 | possible. Similarly, something that a variable represents may only be
729 | in two states. Booleans are used to represent these variables.
730 |
731 | #### Nil
732 |
733 | Nil is a special type of value in Lua. It is the value used when a
734 | variable is not assigned. For instance, take the example below:
735 |
736 | ```lua
737 | Index = 1
738 | print( index ) -- nil
739 | ```
740 |
741 | Note here that the variable assigned is `Index`, while the variable
742 | accessed is `index`. Because these are different variables (remember:
743 | capitalization matters), `index` has not been assigned, so it has no
744 | value. So, `nil` is the value given to variables who have not been
745 | assigned.
746 |
747 | You may be wondering: Why is this useful? Why can't Lua just figure out
748 | what variable I'm going for instead of being so pedantic? Because you
749 | don't want your programming language to try to "figure out" anything;
750 | it should do **only** what you tell it to. This is because you can get
751 | hard to find errors if the program thinks you're trying to type one
752 | thing and you mean another.
753 |
754 | Additionally, having the `nil` value is useful for several somewhat
755 | complex reasons. These will be explained more later, but what you need to
756 | know now is that it allows you to check if a variable has been assigned
757 | or not.
758 |
759 | ### The `type` Command
760 |
761 | Just like the `print` command is a part of Lua's standard library,
762 | so to is another command: `type`. The `type` command is used to get a
763 | variable's type. For instance, if you ran
764 |
765 | ```lua
766 | print( type( 3 ) ) -- number
767 | ```
768 |
769 | You would get `number`. That's because `3` is a number. You can see all
770 | the variable types represented:
771 |
772 | ```lua
773 | print( type( 'This is a string' ) ) -- string
774 | print( type( true ) ) -- boolean
775 | print( type( nil ) ) -- nil
776 | ```
777 |
778 | This command is useful for getting information about a variable.
779 |
780 | ### Why would I want to use variables?
781 |
782 | Variables are extremely useful and are the building blocks for a
783 | program. Variables hold many benefits for programmers:
784 |
785 | - Variables make your code easier to read and understand. Variables are
786 | more descriptive than just numbers or strings. You may not know exactly
787 | what `d = 6.28 * r` means or does, but you know exactly what it represents
788 | in the example below:
789 |
790 | ```lua
791 | pi = 3.14
792 | tau = 2 * pi
793 | radius = 5
794 | diameter = tau * radius
795 | ```
796 |
797 | - Variables make changing your code easier. For instance, say your
798 | program gets the area and circumference of a circle. This is what your
799 | program looks like:
800 |
801 | ```lua
802 | radius = 3
803 | area = 3.14 * radius ^ 2
804 | circumference = 2 * 3.14 * radius
805 | ```
806 |
807 | - What happens if you decide you want more precision with your
808 | results? You would be forced to change every occurrence of `3.14` with
809 | whatever the new value is. Of course, in this example, that's only two
810 | times. But you can imagine how much of a pain it would be in an actual
811 | program. It's easier to use a variable for `pi`, and to just change
812 | that one value instead of every individual value, avoiding wasted time
813 | and frustration.
814 |
815 | In summary, variables:
816 |
817 | - Make your code easier to read
818 |
819 | - Make changes easier and faster
820 |
821 | #### Strings vs Numbers
822 |
823 | You may have noticed that strings can store numbers. This may
824 | have caused you to ask yourself, "How do I decide if I should use a
825 | number or a string?" The answer is "It depends." For a simple answer,
826 | numbers that you will be doing mathematical calculations with should be
827 | `numbers`, while numbers that will only be stored or displayed should be
828 | `strings`. For instance, a phone number would usually be stored as a
829 | `string`, as no calculations will be done with a phone number. On the
830 | other hand, a person's age would probably be stored as a `number`, as,
831 | at the very least, it will need to be incremented.
832 |
833 | ### Exercises
834 |
835 | In this section, you will create a file that should act as your
836 | notes. Feel free to add comments liberally to document what it is you're
837 | doing and why. I recommend making a directory on your `Desktop` to keep
838 | all of your files, and naming this file something really clever like
839 | `01 Variable Names and Comments.lua` and opening it with ZeroBrane. Type
840 | the following information to the file:
841 |
842 | ```lua
843 | info1 = 'This is a string'
844 | info2 = 'Strings can store letters and numbers'
845 |
846 | print( info1 )
847 | print( info2 )
848 | ```
849 |
850 | Now run the project. If you've followed the instructions correctly,
851 | the console should output something like this:
852 |
853 | ```
854 | This is a string
855 | Strings can store letters and numbers
856 | ```
857 |
858 | Next, you will want some notes on variable names:
859 |
860 | ```lua
861 | thisIsCamelCase = true
862 | this_is_snake_case = true
863 |
864 | print( thisIsCamelCase )
865 | print( this_is_snake_case )
866 |
867 | 1invalidName = true
868 | also bad = true
869 | don't-bother = true
870 | ```
871 |
872 | When you run the file you should see an error that says something like:
873 |
874 | ```
875 | lua: 01 Variables and Comments.lua:13: unexpected symbol near '1'`
876 | ```
877 |
878 | Let's break down this error:
879 |
880 | - `lua:`: This tells you that the error is a Lua error.
881 |
882 | - `01 Variables and Comments.lua`: This is the file in which the error
883 | occurs.
884 |
885 | - `13:` This tells you the line on which the error occurred. If the line
886 | isn't exactly 13, don't worry. (In fact, it should probably be past 13
887 | because of all the comments you've added!)
888 |
889 | - `unexpected symbol near '1'`: This tells you that there is something
890 | that was not expected near `1`. If you remember from earlier, variable
891 | names in Lua cannot start with numbers. To get rid of this error, change
892 | that line to something like this:
893 |
894 | ```lua
895 | -- 1invalidName = false
896 | -- Variable names can't start with numbers!
897 | ```
898 |
899 | When you run the file again, you should get another error:
900 |
901 | ```
902 | lua: test.lua:14: syntax error near 'bad'
903 | ```
904 |
905 | This time, the syntax error is near `bad`. This is because variables
906 | in Lua cannot have spaces! The Lua interpreter is expecting something
907 | after the space, such as a comma or equal-sign. To get rid of this,
908 | comment out the line and add some notes.
909 |
910 | When you run the file again, you should get yet another error:
911 |
912 | ```
913 | lua: test.lua:15: unfinished string near ''t-bother = true'
914 | ```
915 |
916 | This is because the `'` indicates the start of a string. In Lua, strings
917 | can't be multiple lines. (Actually, they can, but you need to use special
918 | characters to indicate this). At any rate, the string isn't enclosed,
919 | so the error is still valid. Get rid of the quote to get rid of that
920 | error message, and add a comment noting so. Now, you're greeted with a
921 | new error:
922 |
923 | ```
924 | lua: test.lua:15: syntax error near '-'
925 | ```
926 |
927 | This is because you can't have dashes within a variable name. Comment
928 | out the line to get rid of the error.
929 |
930 | Now add the following:
931 |
932 | ```lua
933 | booleanVariable = true
934 | stringVariable = 'string'
935 | numberVariable = 123
936 | multiLineString = [[
937 | This is a
938 | string that spans
939 | mutliple lines
940 | ]]
941 |
942 | --[[
943 | This comment also
944 | spans mutliple lines
945 | ]]
946 |
947 | print( booleanVariable )
948 | print( stringVariable )
949 | print( numberVariable )
950 | print( multiLineString )
951 | print( thisVariableIsNil )
952 | ```
953 |
954 | **Remember**: This is supposed to serve as *your* notes. Add more if you
955 | think it's necessary. (You should have **much** more than I have here).
956 |
957 |
958 |
959 |
960 |
961 | ## Basic Loops
962 |
963 | Sometimes when you are programming, there will be a task that is repeated
964 | many times. For instance, say you want to print your name five times. You
965 | could write something that looks like this:
966 |
967 | ```lua
968 | name = 'John Smith'
969 |
970 | print( name )
971 | print( name )
972 | print( name )
973 | print( name )
974 | print( name )
975 | ```
976 |
977 | As a programmer, you should strive to be as lazy when typing as
978 | possible. This means that the above code is a big no-no. The main
979 | reason for this is that it is difficult to change. Say, for instance,
980 | you want to print your name 10 times. That means copying and pasting
981 | everything. (***Hopefully*** you didn't consider typing all of that!) This
982 | is unwieldy, but manageable. But what happens if you want to print your
983 | name ***100*** times? This would be a real pain to type and would be
984 | ridiculous. But what about a **variable** number of times? This would
985 | be impossible with what you currently know. Thankfully, Lua includes a
986 | construct that is ideal for this type of situation: the `for-loop`.
987 |
988 | ### Numeric For-Loops
989 |
990 | Instead of writing everything multiple times, you can use what are
991 | called **numeric for-loops**. The name might be scary, but all it does
992 | is do something a certain number of times. This is the basic structure
993 | of this loop is (you should **not** run this):
994 |
995 | ```lua
996 | for VAR = START, END, INCREMENT do
997 | -- Code
998 | end
999 | ```
1000 |
1001 | In the above code, `VAR` is a variable that represents the current index
1002 | of the loop. `START` represents the number at which the loop begins,
1003 | `END` represents the number at which the loop stops, and `INCREMENT`
1004 | is the amount by which to increase (or decrease) `VAR` at the end of
1005 | each loop. If `INCREMENT` is not given, it defaults to `1`.
1006 |
1007 | Below is a basic example of a for-loop:
1008 |
1009 | ```lua
1010 | for index = 1, 5, 1 do
1011 | print( index )
1012 | end
1013 |
1014 | --[[
1015 | 1
1016 | 2
1017 | 3
1018 | 4
1019 | 5
1020 | ]]
1021 | ```
1022 |
1023 | Note that, because the increment is `1` by default, this loop is the
1024 | same as
1025 |
1026 | ```lua
1027 | for index = 1, 5 do
1028 | print( index )
1029 | end
1030 | ```
1031 |
1032 | In most cases, you will want to increment by one, but you can increment by
1033 | any real number. For instance, if you wanted even numbers, you could do:
1034 |
1035 | ```lua
1036 | for i = 2, 10, 2 do
1037 | print( i )
1038 | end
1039 |
1040 | --[[
1041 | 2
1042 | 4
1043 | 6
1044 | 8
1045 | 10
1046 | ]]
1047 | ```
1048 |
1049 | You can also use a variable as the `STOP` or increment. For instance,
1050 | in the above example, where you wanted to print your name a certain
1051 | amount of times, you would do something like this, changing `times`
1052 | to the number of times you would like to print the person's name.
1053 |
1054 | ```lua
1055 | name = 'John Smith'
1056 | times = 100
1057 |
1058 | for index = 1, times do
1059 | print( name )
1060 | end
1061 | ```
1062 |
1063 | This is **much** better than typing all of the original code out and
1064 | changing it all the time.
1065 |
1066 | #### Using the Stop and Increment Controllers
1067 |
1068 | You may remember the parts of the for-loop labeled `STOP` and `INCREMENT`
1069 | from before. These two variables work in conjunction with each-other
1070 | to control how many times the for-loop loops. The loop will continue
1071 | until the index will have surpassed `STOP`. Here are some examples of
1072 | how different loops work:
1073 |
1074 | ```lua
1075 | for i = 1, 8, 2 do
1076 | print( i )
1077 | end
1078 | --[[
1079 | 1
1080 | 3
1081 | 5
1082 | 7
1083 | ]]
1084 |
1085 | for i = 8, 1, -2 do
1086 | print( i )
1087 | end
1088 | --[[
1089 | 8
1090 | 6
1091 | 4
1092 | 2
1093 | ]]
1094 | ```
1095 |
1096 | Note that in each of the above examples, if the loop would have executed
1097 | one more time, the index would have surpassed `STOP`.
1098 |
1099 | ### While-Loops
1100 |
1101 | While loops rely on [booleans](#booleans) to control their flow. A
1102 | while-loop executes **while** the condition is true. For instance, if
1103 | you wanted to implement a simple incrementing for-loop, you would do
1104 | something like this:
1105 |
1106 | ```lua
1107 | index = 1
1108 | while index < 5 do
1109 | print( index )
1110 | index = index + 1
1111 | end
1112 |
1113 | --[[
1114 | 1
1115 | 2
1116 | 3
1117 | 4
1118 | ]]
1119 | ```
1120 |
1121 | A look at how the loop works helps to understand why it prints 1-4 and
1122 | not 5. This is what the loop looks like at each step of execution (do
1123 | **not** run the following code; it is simply an illustration of what
1124 | is occurring):
1125 |
1126 | ```
1127 | Is 1 < 5? Yes, so:
1128 | print( 1 )
1129 | index = 1 + 1 -- (index now is equal to 2)
1130 | Check condition again
1131 |
1132 | Is 2 < 5? Yes, so:
1133 | print( 2 )
1134 | index = 2 + 1 -- (index = 3)
1135 | Check condition again
1136 |
1137 | Is 3 < 5? Yes, so:
1138 | print( 3 )
1139 | index = 3 + 1
1140 | Check condition again
1141 |
1142 | Is 4 < 5? Yes, so:
1143 | print( 4 )
1144 | index = 4 + 1
1145 | Check condition again
1146 |
1147 | Is 5 < 5? No, so stop.
1148 | ```
1149 |
1150 | Now it is obvious why 5 is not output: the loop only executes while the
1151 | given condition is `true`, then quits.
1152 |
1153 | Note that it is **essential** to assign the variable *before* the
1154 | while-loop. The concept is a bit complicated, but essentially, you
1155 | can't compare `index` and `5` if `index` has no value yet. Consider the
1156 | following example:
1157 |
1158 | ```lua
1159 | index = nil
1160 | while index < 10 do
1161 | print( index )
1162 | index = index + 1
1163 | end
1164 | ```
1165 |
1166 | Because you have not assigned `index` a value yet, you will get the error
1167 | "Attempt to compare a number with [nil](#nil)." This is because you're
1168 | essentially asking the interpreter to compare `nil` with `5`. Because
1169 | `nil` has no value, you cannot compare it with a number, hence causing
1170 | the error above.
1171 |
1172 | As long as the statement between the `while` and `do` is `true`, the
1173 | loop will continue to repeat. The general structure of a while-loop is:
1174 |
1175 | ```lua
1176 | while ( BOOLEAN ) do
1177 | -- Code
1178 | end
1179 | ```
1180 |
1181 | `BOOLEAN` is a value that is updated every loop. If `BOOLEAN` is **not**
1182 | updated every loop, you will end up with an **infinite loop**.
1183 |
1184 | #### Infinite Loops
1185 |
1186 | An infinite loop will execute until you terminate the execution. You
1187 | can interrupt the execution of the process by pressing `Ctrl` and `c`
1188 | at the same time. This tells the Lua interpreter to quit what it was
1189 | doing and is called **breaking** the execution. For instance, type the
1190 | following into the interpreter:
1191 |
1192 | ```lua
1193 | while true do
1194 | print( 'infinite' )
1195 | end
1196 | ```
1197 |
1198 | Notice that this will continue executing until you break it using
1199 | `Ctrl+c`.
1200 |
1201 | #### Break
1202 |
1203 | There is also a command that can also be used to abort the execution of
1204 | a loop called `break`. This is used if you want to stop the execution
1205 | of a loop for any reason. Take the following example:
1206 |
1207 | ```lua
1208 | index = 1
1209 |
1210 | while index < 5 do
1211 | print( index )
1212 | index = index + 1
1213 | break
1214 | print( 'You should not see this!' )
1215 | end
1216 | -- 1
1217 |
1218 | print( index ) -- 2
1219 | ```
1220 |
1221 | Note that the code after the `break` command is not executed. This is
1222 | because that part is completely ignored because of the `break` command.
1223 |
1224 | The `break` command ended the loop before the execution completed. This
1225 | may not seem useful now, but it will become more useful later when you
1226 | have learned about more advanced structures, such as `if-then` statements,
1227 | which will be discussed in the next section.
1228 |
1229 | ### Repeat-Until Loops
1230 |
1231 | Repeat-until loops are very similar to `while` loops. While `while`
1232 | loops execute execute **while** a condition is `true`, `repeat-until`
1233 | loops execute until a condition is met. These two loops have the same
1234 | output, but their structure is very different:
1235 |
1236 | ```lua
1237 | -- while-loop
1238 | i = 0
1239 | while ( i < 5 ) do
1240 | i = i + 1
1241 | end
1242 | print( i ) -- 5
1243 |
1244 | -- repeat-until loop
1245 | i = 0
1246 | repeat
1247 | i = i + 1
1248 | until ( i > 4 )
1249 |
1250 | print( i ) -- 5
1251 | ```
1252 |
1253 | You may be wondering: What is the advantage of using a `while` loop versus
1254 | a `repeat` loop? Personal preference is certainly one reason, but there is
1255 | one other advantage: a `repeat` loop will **always** execute *at least*
1256 | one time, while `while` loops may not execute at all. This may seem
1257 | odd at first, but it makes sense: If the initial condition of a `while`
1258 | loop is `false`, the loop never executes. Test the following loops out:
1259 |
1260 | ```lua
1261 | i = 5
1262 | while i < 5 do
1263 | print( i )
1264 | i = i + 1
1265 | end
1266 | -- No output from the loop
1267 | print( i ) -- 5
1268 |
1269 | i = 5
1270 | repeat
1271 | print( i )
1272 | i = i + 1
1273 | until i > 4
1274 | -- 5
1275 | print( i ) -- 6
1276 | ```
1277 |
1278 | Note that in both of `while` and `repeat` loops, you **can** surround
1279 | the boolean expression with parenthesis if you'd like. In fact, all of
1280 | the following are valid ways to express loops:
1281 |
1282 | ```lua
1283 | i = 0
1284 | while i < 5 do
1285 | i = i + 1
1286 | end
1287 | print( i )
1288 |
1289 | i = 0
1290 | while ( i < 5 ) do
1291 | i = i + 1
1292 | end
1293 | print( i )
1294 |
1295 | i = 0
1296 | while i < 5 do i = i + 1 end
1297 | print( i )
1298 | ```
1299 |
1300 | All of the following are valid, as well as several other ways. This is
1301 | another one of the advantages of Lua: you don't have to format your
1302 | code a certain way. As long as the entire word is complete (i.e. not
1303 | separated by a space or new line), it doesn't matter how the code is
1304 | formatted. I would **strongly** recommend avoiding the third method,
1305 | however, as it is harder to read and understand.
1306 |
1307 | ### Exercises
1308 |
1309 | You may have noticed that for-loops, while-loops, and repeat-until loops
1310 | can all be used to do the same things. Start by creating a file called
1311 | `02 Basic Loops.lua` and creating a for-loop that counts from 1 to 10:
1312 |
1313 | ```lua
1314 | for 1, 10, 1 do
1315 | print( index )
1316 | end
1317 | ```
1318 |
1319 | You should get an error saying ` expected near '1'`. That's because
1320 | you forgot to assign `index`! Fix it by changing the loop to:
1321 |
1322 | ```lua
1323 | for index = 1, 10, 1 do
1324 | print( index )
1325 | end
1326 | ```
1327 |
1328 | Now try going from 10 to 1 with a for-loop:
1329 |
1330 | ```lua
1331 | for index = 10, 1 do
1332 | print( index )
1333 | end
1334 | ```
1335 |
1336 | You should notice that there is no new output. This is because the
1337 | default increment is `1`. Because the index is already past `1`, the
1338 | loop does nothing. To fix this, change the increment to `-1`.
1339 |
1340 | Now make a while-loop that counts from 1 to 10:
1341 |
1342 | ```lua
1343 | while counter < 10 do
1344 | counter = counter + 1
1345 | print( counter )
1346 | end
1347 | ```
1348 |
1349 | You should get an error that says: `attempt to compare nil with a
1350 | number`. That's because you never assigned `counter`. Assign counter to
1351 | `1`. Now you should get an output, but wait! The loop prints `2` first,
1352 | instead of `1`. To fix this, you need to change `counter` to be `0`. Note
1353 | that this happens because you increment the variable, **then** output it,
1354 | so while counter *starts* at `1`, it becomes `2` before it is displayed.
1355 |
1356 | Now make a while-loop that counts from 10 to 1:
1357 |
1358 | ```lua
1359 | downCounter = 10
1360 | while downCounter < 1 do
1361 | downCounter = downCounter + 1
1362 | print( downCounter )
1363 | end
1364 | ```
1365 |
1366 | When you run this, you should get no output. That's because the initial
1367 | condition is not `true`, so it never executes. Change that to be
1368 |
1369 | ```lua
1370 | while downCounter > 1 do
1371 | ```
1372 |
1373 | You should get an infinite loop this time. Remember to break output by
1374 | pressing `Ctrl` and `c` at the same time. Can you see why you get an
1375 | infinite loop? It's because the condition will never change: 10 > 1,
1376 | 11 > 1, and so on. You need to change the reassignment of `downCounter`
1377 | to decrement (go down by one) instead of increment (increase by one).
1378 |
1379 | Finally, make a repeat-until loop that counts from 1 to 10 and another
1380 | that counts from 10 to 1. The first one should look something like this:
1381 |
1382 | ```lua
1383 | repeat
1384 | print( counter )
1385 | counter = counter + 1
1386 | until counter > 9
1387 | ```
1388 |
1389 | You may have been expecting an error because `counter` was not defined,
1390 | but instead what you got was an infinite loop. Why is that? Because you
1391 | used `counter` in the first while-loop you created. So you either need to
1392 | reassign `counter` or choose another variable (and assign it). Reassign
1393 | the variable here, like so:
1394 |
1395 | ```lua
1396 | counter = 0
1397 | repeat
1398 | print( counter )
1399 | counter = counter + 1
1400 | until counter > 9
1401 | ```
1402 |
1403 | Finally, use a repeat-until loop to count from 10 to 1, using the same
1404 | variable as you used for the first repeat-until loop:
1405 |
1406 | ```lua
1407 | repeat
1408 | print( counter )
1409 | counter = counter - 1
1410 | until counter < 1
1411 | ```
1412 |
1413 | ***Remember*** to add *lots* of comments to the file! These are your
1414 | notes!
1415 |
1416 |
1417 |
1418 |
1419 |
1420 | ## If-Then Statements
1421 |
1422 | Sometimes when you are programming, you only want to do something **if**
1423 | some other thing is true. For instance, you may want your while-loop to
1424 | quit after it executes 100 times. You would use an **if-then** statement
1425 | to do this. These follow the following structure (you should **not**
1426 | run this file):
1427 |
1428 | ```lua
1429 | if ( BOOLEAN ) then
1430 | -- Code
1431 | end
1432 | ```
1433 |
1434 | For instance, you could display if a person's age is over 18:
1435 |
1436 | ```lua
1437 | age = 21
1438 |
1439 | if age > 18 then
1440 | print( 'This person is over 18' )
1441 | end
1442 | -- This person is over 18
1443 | ```
1444 |
1445 | You may have noticed by now there are several different ways to compare
1446 | numbers. You've seen some of them, and may be familiar with some, but
1447 | there are still several more which will be discussed below.
1448 |
1449 | ### Comparisons
1450 |
1451 | In math, there are several operators that you may be familiar with:
1452 |
1453 | - Equal to
1454 |
1455 | - Not equal to
1456 |
1457 | - Greater than
1458 |
1459 | - Less than
1460 |
1461 | - Greater than or equal to
1462 |
1463 | - Less than or equal to
1464 |
1465 | These can all be expressed in Lua as follows:
1466 |
1467 | | Mathematical expression | Lua equivalent |
1468 | |--------------------------|----------------|
1469 | | Equal to | `==` |
1470 | | Not equal to | `~=` |
1471 | | Greater than | `>` |
1472 | | Less than | `<` |
1473 | | Greater than or equal to | `>=` |
1474 | | Less than or equal to | `<=` |
1475 | | Modulo | `%` |
1476 |
1477 | You may not be familiar with some of these operators, such as modulo,
1478 | but don't worry, they will be explained shortly.
1479 |
1480 | It may seem odd that "equal to" is `==`, but it actually makes sense:
1481 | because `=` is for assignment, `==` is for comparison; it helps to
1482 | distinguish the two.
1483 |
1484 | You have already seen some of the above operators in the [Basic
1485 | Loops](#basic-loops) section. You can see the operators in-action with
1486 | some examples (remember to run this on the interactive Lua command line):
1487 |
1488 | ```lua
1489 | if 3 > 2 then
1490 | print( '3 > 2' )
1491 | end
1492 |
1493 | if 3 >= 3 then
1494 | print( '3 >= 3' )
1495 | end
1496 |
1497 | if 3 ~= 2 then
1498 | print( '3 is not equal to 2' )
1499 | end
1500 | ```
1501 |
1502 | Note that all of these commands work **only** for numbers, except for
1503 | `==` and `~=`, as demonstrated below:
1504 |
1505 | ```lua
1506 | str1 = 'This is a test'
1507 | str2 = 'This is a test'
1508 |
1509 | if str1 == str2 then
1510 | print( 'These are both tests' )
1511 | end
1512 |
1513 | bool1 = true
1514 | bool2 = true
1515 |
1516 | if bool1 == bool2 then
1517 | print( 'These booleans are equal' )
1518 | end
1519 | ```
1520 |
1521 | #### Modulo
1522 |
1523 | The `modulo` operator gives the remainder of a number after division. For
1524 | instance, `4 % 3` is 1, because the result of `4 / 3` is 1 with a
1525 | remainder of 1. You can use this in many ways. For instance, a number
1526 | is even if the result of its modulo with 2 is 0.
1527 |
1528 | ```lua
1529 | number = 10
1530 | if number % 2 == 0 then
1531 | print( 'This number is even' )
1532 | end
1533 | ```
1534 |
1535 | #### The Length Operator
1536 |
1537 | There is also another operator that *cannot* be used with numbers or
1538 | booleans: `#`, the **length** operator. This gives you the length,
1539 | for instance, of a string, in characters. For instance:
1540 |
1541 | ```lua
1542 | test1 = 'test'
1543 | print( #test1 ) -- 4
1544 |
1545 | test2 = 'test2'
1546 | print( #test2 ) -- 5
1547 |
1548 | test3 = 'test again'
1549 | print( #test3 ) -- 10
1550 | ```
1551 |
1552 | This can have several applications. For instance, if a user's password
1553 | must have a certain length, you could alert them:
1554 |
1555 | ```lua
1556 | password = 'hunter2'
1557 |
1558 | if #password < 10 then
1559 | print( 'Error: your password is not long enough!' )
1560 | end
1561 | ```
1562 |
1563 | #### Assigning Booleans
1564 |
1565 | You've seen before that you can assign booleans by giving it either
1566 | a value of `true` or `false`. But a boolean can also be assigned by a
1567 | value. For instance, if you wanted to represent that a comparison with
1568 | a boolean, you could do:
1569 |
1570 | ```lua
1571 | age = 18
1572 |
1573 | canSmoke = age >= 18
1574 | canDrink = ( age >= 21 )
1575 |
1576 | print( 'You can smoke: ', canSmoke ) -- You can smoke: true
1577 | print( 'You can drink: ', canDrink ) -- You can smoke: false
1578 | ```
1579 |
1580 | Note that surrounding the condition in parenthesis, while not required,
1581 | is recommended for clarity.
1582 |
1583 | Notice that for `canSmoke`, `age >= 18` returns `true`, because `18 >=
1584 | 18`. For the `canDrink`, however, `18 >= 21` is `false`, so `canDrink`
1585 | is `false`.
1586 |
1587 | This is actually how the comparison in if-then statements work, as
1588 | well as the while-loops and repeat-until loops. It simply checks if
1589 | the condition is equal to `true`. For instance, the following two if
1590 | statements are equivalent:
1591 |
1592 | ```lua
1593 | name = 'John'
1594 |
1595 | if #name == 4 then
1596 | print( name .. ' is four letters long' )
1597 | end
1598 |
1599 | -- or
1600 |
1601 | name = 'John'
1602 |
1603 | if ( #name == 4 ) == true then
1604 | print( name .. ' is four letters long' )
1605 | end
1606 | ```
1607 |
1608 | Notice that the parenthesis in the second example are *completely*
1609 | optional, though I **strongly** recommend using them for clarity's sake.
1610 |
1611 | ### Else
1612 |
1613 | But what if the comparison is **not true**? Lua includes an extension of
1614 | the if-then statement. This is called **else**. If the condition is not
1615 | `true`, the else branch is executed. The basic structure is (not that
1616 | you should **not** run this):
1617 |
1618 | ```lua
1619 | if BOOLEAN then
1620 | -- Code
1621 | else
1622 | -- Other code
1623 | end
1624 | ```
1625 |
1626 | Here's an example:
1627 |
1628 | ```lua
1629 | if 3 > 5 then
1630 | print( 'What\'s going on?' )
1631 | else
1632 | print( 'That\'s more like it!' )
1633 | end
1634 | -- That's more like it!
1635 | ```
1636 |
1637 | ### Elseif
1638 |
1639 | Now we have cases for where the boolean is `true` and `false`. But
1640 | what about when you want to make multiple comparisons? You *could*
1641 | do something like this (note that you should **not** run this):
1642 |
1643 | ```lua
1644 | if firstBoolean then
1645 | -- Code
1646 | else
1647 | if secondBoolean then
1648 | -- More code
1649 | else
1650 | if thirdBoolean then
1651 | -- Even more code
1652 | else
1653 | -- Etc
1654 | end
1655 | end
1656 | end
1657 | ```
1658 |
1659 | This works, but can become unmanageable very quickly. Instead, Lua has
1660 | what is called an **elseif** statement. This is for when a variable can
1661 | be in multiple states, such as a string. For instance:
1662 |
1663 | ```lua
1664 | -- Run this several times, alternating `name` between 'Joe', 'Frank', and 'Bob'
1665 | name = 'Joe'
1666 |
1667 | if name == 'Joe' then
1668 | print( 'Joe is not cool enough to be a part of our club!' )
1669 | elseif name == 'Frank' then
1670 | print( 'Frank is almost cool enough to be a part of our club!' )
1671 | elseif name == 'Bob' then
1672 | print( 'Bob is definitely not cool enough to be a part of our club!' )
1673 | else
1674 | print( 'Who are you?' )
1675 | end
1676 | ```
1677 |
1678 | Note that capitalization **does** matter. `'frank'` ~= `'Frank'` and
1679 | so on. You can even have if statements within if-then statements. For
1680 | instance, if the length of the name is the fallback condition for joining
1681 | the secret club mentioned above, you could do this:
1682 |
1683 | ```lua
1684 | name = 'Joe'
1685 |
1686 | if name == 'Joe' then
1687 | print( 'Joe is not cool enough to be a part of our club!' )
1688 | elseif name == 'Frank' then
1689 | print( 'Frank is almost cool enough to be a part of our club!' )
1690 | elseif name == 'Bob' then
1691 | print( 'Bob is definitely not cool enough to be a part of our club!' )
1692 | else
1693 | -- Only let them in if their name is longer than 6 letters
1694 | nameLength = #name
1695 | if nameLength > 6 then
1696 | print( 'You\'re in, ' .. name .. '!' )
1697 | elseif nameLength >= 5 then
1698 | print( 'You\'re almost cool enough, ' .. name .. '.' )
1699 | else
1700 | print( 'Sorry, you\'re not cool enough, ' .. name .. '.' )
1701 | end
1702 | end
1703 | ```
1704 |
1705 | Notice the first `elseif` statement: the first condition (`if nameLength >
1706 | 6`) is only `true` if the number is greater than 6, which does **not**
1707 | include 6. The next statement (`elseif nameLength >= 5`) will *only*
1708 | trigger if `nameLength` is 5 or 6 letters long.
1709 |
1710 | ### Boolean Operators
1711 |
1712 | Sometimes you would like to do the same thing if two conditions are
1713 | met. You **could** do this:
1714 |
1715 | ```lua
1716 | if cond1 then
1717 | -- Code
1718 | elseif cond2 then
1719 | -- Exact same code
1720 | else
1721 | -- Etc
1722 | end
1723 | ```
1724 |
1725 | Other times you would like to only execute code if more than one condition
1726 | is met. You **could** do this:
1727 |
1728 | ```lua
1729 | if cond1 then
1730 | if cond2 then
1731 | if cond3 then
1732 | -- Code
1733 | end
1734 | end
1735 | end
1736 | ```
1737 |
1738 | Of course, as I'm sure you're probably thinking by now, there are *much*
1739 | better alternatives. Both of the above *work*, but are not flexible
1740 | enough to be real solutions. Instead, there are two **boolean operators**:
1741 | **or** and **and**.
1742 |
1743 | #### Or
1744 |
1745 | Or works just like you'd expect it to: It returns true if *either*
1746 | of the conditions are `true`. For instance:
1747 |
1748 | ```lua
1749 | print( ( 3 > 1 ) or ( 3 > 5 ) ) -- True
1750 | print( ( 3 > 1 ) or ( 3 < 5 ) ) -- True
1751 | print( ( 3 < 1 ) or ( 3 < 5 ) ) -- True
1752 | print( ( 3 < 1 ) or ( 3 > 5 ) ) -- False
1753 | ```
1754 |
1755 | This can be utilized within the boolean condition for while loops *or*
1756 | if-then statements (see what I did there?):
1757 |
1758 | ```lua
1759 | iterations = 0
1760 | condition = false
1761 |
1762 | while ( iterations <= 100 ) or ( condition ) do
1763 | condition = false
1764 | iterations = iterations + 1
1765 | print( 'Still looping!' )
1766 | end
1767 |
1768 | print( 'Done looping!' )
1769 | ```
1770 |
1771 | ```lua
1772 | name = 'Blake'
1773 |
1774 | if name == 'John' or #name == 5 then
1775 | print( 'Hiya, ' .. name )
1776 | else
1777 | print( 'Who are you?' )
1778 | end
1779 | ```
1780 |
1781 | #### And
1782 |
1783 | While `or` is used for *either* condition, `and` is used for *both*
1784 | conditions. For example:
1785 |
1786 | ```lua
1787 | superCool = true
1788 | superSmart = true
1789 |
1790 | if superCool and superSmart then
1791 | print( 'I am super cool and super smart' )
1792 | elseif superCool or superSmart then
1793 | print( 'One out of two \'aint bad!' )
1794 | else
1795 | print( 'At least I have my personality!' )
1796 | end
1797 | ```
1798 |
1799 | Try changing around the booleans in the above example to see how that
1800 | affects the execution of the code.
1801 |
1802 | #### Not
1803 |
1804 | While `and` and `or` work with two conditions, `not` works with only
1805 | one. It **negates** the operation. Essentially what it does is swap the
1806 | boolean. For instance:
1807 |
1808 | ```lua
1809 | cool = true
1810 | notCool = not cool
1811 |
1812 | print( cool ) -- true
1813 | print( notCool ) -- false
1814 | ```
1815 |
1816 | But `not` can be used on more than just booleans. In Lua, anything that
1817 | is not `false` or `nil` is `true`, so `not` would make those statements
1818 | `false`:
1819 |
1820 | ```lua
1821 | print( not true ) -- false
1822 | print( not 100 ) -- false
1823 | print( not 'My name is John' ) -- false
1824 |
1825 | print( not false ) -- true
1826 | print( not nil ) -- true
1827 | ```
1828 |
1829 | You can get the "truthiness" of a value by negating it *twice*. For
1830 | instance, you know that a string is "truthy", because
1831 |
1832 | ```lua
1833 | print( not not 'This is truthy' ) -- true
1834 | ```
1835 |
1836 | This is because `not true` is `false`, so `not not true` is the same as
1837 | `not false`, which is `true`.
1838 |
1839 | Because `nil` is `false`, you have to be careful when you're doing if
1840 | statements, otherwise a `nil` variable can have unexpected results:
1841 |
1842 | ```lua
1843 | superCool = true
1844 |
1845 | if SuperCool then
1846 | print( 'I am super cool!' )
1847 | else
1848 | print( 'Why am I not cool? :(' )
1849 | end
1850 | ```
1851 |
1852 | Note that, because `SuperCool` is not defined, it evaluates to `nil`,
1853 | causing the statement to be `false`.
1854 |
1855 | ### Using If-Statements with Break
1856 |
1857 | If you recall from the previous section, you learned about the `break`
1858 | command. Recall also that, with `if-then` statements, if `BOOLEAN` is
1859 | `true`, the code executes. Otherwise, nothing happens. So if you wanted
1860 | to `break` a `while-loop` after 100 executions, you would do something
1861 | like this:
1862 |
1863 | ```lua
1864 | numberOfTimes = 1
1865 | booleanThatWontChange = true
1866 |
1867 | while booleanThatWontChange do
1868 | numberOfTimes = numberOfTimes + 1
1869 | print( numberOfTimes )
1870 | if numberOfTimes > 99 then
1871 | print( 'That loop went on way too long!' )
1872 | break
1873 | end
1874 | end
1875 | ```
1876 |
1877 | ### Exercises
1878 |
1879 | Create a file called `03 Conditionals.lua`. Within it, create an
1880 | if-elseif-else statement that determines if a person can join your super
1881 | secret club. The criteria are:
1882 |
1883 | - If they're a guy:
1884 |
1885 | - They have to be over 21
1886 |
1887 | - Their name cannot be over 7 letters long
1888 |
1889 | - If they're a girl:
1890 |
1891 | - They have to be over 18 and under 30
1892 |
1893 | You need specific reasoning as to why they were denied admission to the
1894 | club as well.
1895 |
1896 | There are several ways that you could implement this. See if you can
1897 | figure it out yourself first, before looking at the solution below:
1898 |
1899 | ```lua
1900 | name = 'John'
1901 | age = 23
1902 | male = true
1903 |
1904 | if male then
1905 | -- Male
1906 | if age >= 21 then
1907 | if #name <= 7 then
1908 | print( 'You\'re in, ' .. name .. '!' )
1909 | print( 'First round\'s on you!' )
1910 | else
1911 | print( 'Sorry, you\'re name is way too long' )
1912 | print( 'Not enough room on our name tags' )
1913 | end
1914 | else
1915 | print( 'Sorry, you\'ll need to come back when you\'re older' )
1916 | end
1917 | else
1918 | -- Female
1919 | if age >= 18 then
1920 | if age <= 30 then
1921 | print( 'Come on in, ' .. name )
1922 | else
1923 | print( 'Sorry, you\'re way too old!' )
1924 | print( 'There\'s a retirement home across the street' )
1925 | end
1926 | else
1927 | print( 'You\'re not old enough!' )
1928 | end
1929 | ```
1930 |
1931 | When you run the file, if you've typed it **exactly** as I have,
1932 | you should get the error `lua: 03 Conditionals.lua:29: 'end' expected
1933 | (to close 'if' at line 1) near .` This error may seem confusing at
1934 | first, but after inspection it is a little more clear: `` if just
1935 | a fancy way to represent the **e**nd **o**f **f**ile. That's because
1936 | you're missing the `end` to close the `-- Female` if-statement.
1937 |
1938 | Of course, this is not the **only** implementation you can use. As with
1939 | any problem, there can be multiple solutions to one problem.
1940 |
1941 | Now say you want to do some error checking to make sure you don't get any
1942 | errors if the user accidentally assigns the value incorrectly. Remember
1943 | the [`type`](#the-type-command) command? You can use this with an
1944 | if-statement to validate the input:
1945 |
1946 | ```lua
1947 | name = 123
1948 | age = '23'
1949 | male = nil
1950 |
1951 | if type( name ) ~= 'string' then
1952 | print( 'Invalid input: name must be a string' )
1953 | elseif type( age ) ~= 'number' then
1954 | print( 'Invalid input: age must be a number' )
1955 | elseif type( male ) ~= 'boolean' then
1956 | print( 'Invalid input: male must be a boolean' )
1957 | else
1958 | if male then
1959 | -- Male
1960 | if age >= 21 then
1961 | if #name <= 7 then
1962 | print( 'You\'re in, ' .. name .. '!' )
1963 | print( 'First round\'s on you!' )
1964 | else
1965 | print( 'Sorry, you\'re name is way too long' )
1966 | print( 'Not enough room on our name tags' )
1967 | end
1968 | else
1969 | print( 'Sorry, you\'ll need to come back when you\'re older' )
1970 | end
1971 | else
1972 | -- Female
1973 | if age >= 18 then
1974 | if age <= 30 then
1975 | print( 'Come on in, ' .. name )
1976 | else
1977 | print( 'Sorry, you\'re way too old!' )
1978 | print( 'There\'s a retirement home across the street' )
1979 | end
1980 | else
1981 | print( 'You\'re not old enough!' )
1982 | end
1983 | end
1984 | ```
1985 |
1986 | Now let's add another example. Say that you want to determine if a number
1987 | is prime. A number is prime if:
1988 |
1989 | 1. The number is only divisible by one and itself
1990 |
1991 | 1. The number is an integer
1992 |
1993 | First, let's test if a number is an integer. There are many ways to
1994 | do this. Recall from earlier, the [modulo](#modulo) operator gives
1995 | the remainder of division. This may not seem to have any application,
1996 | but this can be very useful: if a number is divisible by one it's an
1997 | integer. So, for our prime number checker, let's start by making sure
1998 | that number is an integer:
1999 |
2000 | ```lua
2001 | -- Number to check if it's prime
2002 | number = 3
2003 |
2004 | -- Ensure number is an integer
2005 | if number % 1 == 0 then
2006 | print( 'The number is prime so far!' )
2007 | else
2008 | print( 'The number is not an integer, so it\'s not prime' )
2009 | end
2010 | ```
2011 |
2012 | Change `number` from `3` to `3.1` to see how the results change.
2013 |
2014 | Now let's add a check to see if the number is divisible by any other
2015 | numbers. This can be done with a for loop:
2016 |
2017 | ```lua
2018 | -- Number to check if it's prime
2019 | number = 3
2020 |
2021 | -- Ensure number is an integer
2022 | if number % 1 == 0 then
2023 | -- Check if a number is divisible by any other numbers
2024 | for i = 2, number - 1 do
2025 | if number % i == 0 then
2026 | -- Number is divisible by another number
2027 | print( 'This number is divisible by ', i, 'so it is not prime' )
2028 | else
2029 | print( 'This number is prime!' )
2030 | end
2031 | end
2032 | else
2033 | print( 'The number is not an integer, so it\'s not prime' )
2034 | end
2035 | ```
2036 |
2037 | Your output should be `This number is prime!`. It appears that everything
2038 | is working correctly. But change `number` to a prime number other than
2039 | `3`, such as `5`, and your output will not be what you expected. You
2040 | should see that it prints `This number is prime!` 3 times! This makes
2041 | sense if you walk through the for-loop:
2042 |
2043 | ```
2044 | number = 5
2045 |
2046 | for i = 2, 4 do
2047 | i = 2:
2048 | Is 5 divisible by 2? No, so:
2049 | This number is prime!
2050 | i = 3
2051 | Is 5 divisible by 3? No, so:
2052 | This number is prime!
2053 | i = 4
2054 | Is 5 divisible by 4? No, so:
2055 | This number is prime!
2056 | ```
2057 |
2058 | As you can see what we need is some way to determine if the `if-then`
2059 | statement is `true` for **all** executions of the `for-loop`. We can
2060 | use a boolean to represent this:
2061 |
2062 | ```lua
2063 | -- Number to check if it's prime
2064 | number = 3
2065 |
2066 | -- Ensure number is an integer
2067 | if number % 1 == 0 then
2068 | -- Shows whether number is divisible by any other numbers or not
2069 | isDivisible = false
2070 |
2071 | -- Check if a number is divisible by any other numbers
2072 | for i = 2, number - 1 do
2073 | if number % i == 0 then
2074 | -- Number is divisible by another number
2075 | print( 'This number is divisible by ', i, 'so it is not prime' )
2076 |
2077 | -- number is divisible by another number, so set isDivisible to true
2078 | isDivisible = true
2079 | end
2080 | end
2081 |
2082 | -- After the loop is done, check if isDivisible is false
2083 | if not isDivisible then
2084 | print( 'Our number is prime!' )
2085 | end
2086 | else
2087 | print( 'The number is not an integer, so it\'s not prime' )
2088 | end
2089 | ```
2090 |
2091 | A keen observer would note that you could even thrown in a `break`
2092 | statement at the end of the divisibility check, as only one number needs
2093 | to fail for `isDivisible` to become `true`. Now the code works for *most*
2094 | cases. But what about negative numbers? Negative numbers are not prime,
2095 | since the are all divisible by at *least* `1`, `-1`, and themselves. Plus,
2096 | zero and one are not prime numbers either, so we will need to check for
2097 | these as well:
2098 |
2099 | ```diff
2100 | -- Number to check if it's prime
2101 | number = 3
2102 |
2103 | -- Ensure number is an integer
2104 | if number <= 1 then
2105 | print( 'This number is not prime: prime numbers must be > 1' )
2106 | elseif number % 1 == 0 then
2107 | -- Shows whether number is divisible by any other numbers or not
2108 | isDivisible = false
2109 |
2110 | -- Check if a number is divisible by any other numbers
2111 | for i = 2, number - 1 do
2112 | if number % i == 0 then
2113 | -- Number is divisible by another number
2114 | print( 'This number is divisible by ', i, 'so it is not prime' )
2115 |
2116 | -- number is divisible by another number, so set isDivisible to true
2117 | isDivisible = true
2118 | end
2119 | end
2120 |
2121 | -- After the loop is done, check if isDivisible is false
2122 | if not isDivisible then
2123 | print( 'Our number is prime!' )
2124 | end
2125 | +else
2126 | - print( 'The number is not an integer, so it\'s not prime' )
2127 | end
2128 | ```
2129 |
--------------------------------------------------------------------------------
/gen.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Convert the (unformatted file) to have line wraps for easier viewing in
4 | # terminal
5 |
6 | # Remove the original file
7 | rm LuaGuideFormatted.md
8 |
9 | # Parse through the file, using "```" as the record separator
10 |
11 | awk -v RS='```' '
12 | BEGIN {
13 | inblock = 1; # Indicates if a code block is being processed or not
14 | started = 0; # If the first line is not a code block, it is cut
15 | # off. This keeps that from happening.
16 | }
17 | { inblock = !inblock } # Iterations alternate between code blocks and text
18 | {
19 | if ( inblock ) {
20 | # Code blocks are not formatted, so just output them
21 | print "```" $0 "```" >> "LuaGuideFormatted.md"
22 | }
23 | else {
24 | # Format the text:
25 | # Remove the last line (whitespace) from the heredoc
26 | # which contains the match. A quoted heredoc is used to
27 | # keep quotes and backticks from messing up the command.
28 | system( "( head -n -1 << \"EndOfHereDocument\"\n" $0 \
29 | "\nEndOfHereDocument\n )" \
30 | ( ( started == 1 ) ? "| tail -n +2" : "" ) \
31 | "| fmt -s -w 75 >> LuaGuideFormatted.md" )
32 | # Cut the first couple lines if it is not the first match,
33 | # then format the text
34 | }
35 | started = 1
36 | }' LuaGuide.md
37 |
38 | # Create the HTML file
39 | pandoc -s --number-sections --toc -o LuaGuide.html LuaGuide.md
40 |
--------------------------------------------------------------------------------
/pictures/change-interpreter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/change-interpreter.png
--------------------------------------------------------------------------------
/pictures/create-directory-01-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-directory-01-desktop.png
--------------------------------------------------------------------------------
/pictures/create-directory-02-name-directory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-directory-02-name-directory.png
--------------------------------------------------------------------------------
/pictures/create-directory-03-rename-directory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-directory-03-rename-directory.png
--------------------------------------------------------------------------------
/pictures/create-file-01-file-new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-01-file-new.png
--------------------------------------------------------------------------------
/pictures/create-file-02-untitled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-02-untitled.png
--------------------------------------------------------------------------------
/pictures/create-file-03-file-save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-03-file-save.png
--------------------------------------------------------------------------------
/pictures/create-file-04-file-dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-04-file-dialog.png
--------------------------------------------------------------------------------
/pictures/create-file-05-file-dialog-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-05-file-dialog-desktop.png
--------------------------------------------------------------------------------
/pictures/create-file-06-file-dialog-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/create-file-06-file-dialog-name.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-01-homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-01-homepage.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-02-download-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-02-download-page.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-03-download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-03-download.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-04-choose-installer-location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-04-choose-installer-location.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-05-determine-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-05-determine-architecture.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-06-run-installer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-06-run-installer.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-07-select-install-location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-07-select-install-location.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-08-choose-install-location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-08-choose-install-location.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-09-welcome-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-09-welcome-screen.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-10-create-shortcut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-10-create-shortcut.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-11-shortcut-dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-11-shortcut-dialog.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-12-choose-path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-12-choose-path.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-13-finalize-path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-13-finalize-path.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-14-choose-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-14-choose-name.png
--------------------------------------------------------------------------------
/pictures/installing-zerobrane-15-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/installing-zerobrane-15-result.png
--------------------------------------------------------------------------------
/pictures/run-console-01-change.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/run-console-01-change.png
--------------------------------------------------------------------------------
/pictures/run-console-02-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/run-console-02-output.png
--------------------------------------------------------------------------------
/pictures/run-project-01-run-dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/run-project-01-run-dialog.png
--------------------------------------------------------------------------------
/pictures/run-project-02-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davisdude/LuaGuide/87d07b0c3c5e396eb698d956b235f671af057202/pictures/run-project-02-output.png
--------------------------------------------------------------------------------