├── .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 --------------------------------------------------------------------------------