====== p5js week 03 ====== This week, let's make an automatic toaster in code that can toast 5, 10, or 1,000 pieces of toast for us! After you do that, your goal is to fill your screen with robots, wolves, or flowers. {{:nehal-siksik-124-toaster-robot.jpg?600|}} (toaster robot by Nehal Siksik https://www.artstation.com/artwork/DALome ) To do that, first we need to learn some things about JavaScript: - **reassigning variables** - **incrementing** - **for-loops** - **the remainder operator** Then let's use that in p5js to fill the screens. It's a lot to study, so let's get started! ===== JavaScript ===== First, let's talk about these JavaScript concepts. - [[p5js-week-03#reassigning_variables_and_incrementing|reassigning variables and incrementing]] - [[p5js-week-03#for-loop|for-loops]] ==== reassigning variables and incrementing ==== How could we make a lot of toast? How could we make things change for each piece of toast? What if we wanted to have more and more butter on each slice, or one extra slice of strawberry on each one? {{:stack-of-toast.jpg?600|}} (image from https://www.maxpixel.net/Eat-Delicious-Bread-Toast-Sandwich-Food-Breakfast-4115627 , Creative Commons license) Butter and strawberries might be kind of hard for us to code just now. Let's think about our rainbow toast. We know how to do random colors, but how could we make each piece of toast change color a little bit, slowly going from one color to another? We know from last time that we can represent color with numbers, like RGB. If we slowly change one or more of these numbers, we could slowly change the color. We're going to need to understand how to [[p5js-week-03#reassigning_variables_and_incrementing|increment]] variables. "Increment" ([[https://en.wikipedia.org/wiki/Increment_and_decrement_operators]]) means to increase something by a regular amount. First, remember how variables work. Let's declare a variable: let toastRed = 0 The let keyword protects our variable. toastRed is the variable name. The __equal sign__ is used to assign a value to the variable. Remember, a variable is like a box to keep things in. Do you remember the bread box from before? We can set (assign) this variable to a new number by using the same variable name and a different value: toastRed = 20 Notice that we don't use 'let' when we reassign the variable. Often times, the new value is related to the old value. In that case, we can use the variable name to refer to the old value. toastRed = toastRed + 1 The variable name on the left followed by the __equal sign__ means we are assigning it. Since we assigned it before, that means we are reassigning it now. The value on the right is the old value plus one. In other words, we are adding one to the current value and then storing that new value in the same box (variable). Try evaluating this line multiple times and see what happens. In the same way, we can [[p5js-week-03#reassigning_variables_and_incrementing|decrement]] a number. "Decrement" is the opposite of "[[p5js-week-03#reassigning_variables_and_incrementing|increment]]". It means to make a number go down by steps. toastRed = toastRed - 1 JavaScript gives us a special operator for [[p5js-week-03#reassigning_variables_and_incrementing|incrementing]]. We can use it this way. toastRed = ++toastRed The ++ operator increases a value by one. Try evaluating this line multiple times and see what happens. If you want to [[p5js-week-03#reassigning_variables_and_incrementing|increment]] by another value, you have to use the previous method which is shown above. toastRed = toastRed + 5 In all of the cases above, we assigned a new value to the variable by first writing the variable name on the left and then the new value after writing an __equal sign__. However, there's one more way! toastRed += 10 That adds to the value. You can use this one to subtract: toastRed -= 5 We can use this with a [[p5js-week-03#for-loop|for-loop]], which we are going to learn below, to do that gradual color change. When we get to a value of 255 for red (and 0 for the others), we'll get red toast! {{:red-toast.jpg?600|}} (image from https://commons.wikimedia.org/wiki/File:Ajvar_toast.jpg) =====for-loop===== Now we want to start learning a really important concept: for-loops. Above, we were [[p5js-week-03#reassigning_variables_and_incrementing|incrementing]] numbers. It might be OK to repeat that code three times, but repeating it five times would be a little annoying. Imagine if you had to do it 10 times, or 100 times. What if you had to do it 1,000 times? Can you imagine toasting 1,000 pieces of toast? {{:lots-of-toast.jpg?600|}} (photo by Rohit https://pixahive.com/portfolio/rohit/) Take a look at this function. function toaster (n) { for (let i = 0; i < n; i++) { console.log("have a piece of toast! " + i) } } Try calling it in the console, just like you would do to any function: toaster(10) Maybe you think 10 times is easy. What about 1000? toaster(1000) It contains a [[p5js-week-03#for-loop|for-loop]]. A [[p5js-week-03#for-loop|for-loop]] has a particular structure: the conditions for the [[p5js-week-03#for-loop|for-loop]] are in __parentheses__ and the body of the [[p5js-week-03#for-loop|for-loop]] is in __curly braces__: for () {} ==== the parts of a for-loop ==== {{:butter_sprouted_bread_toast_sweet_drink_jam_coffee.jpg?600|}} In the __parentheses__, you need three parts (kind of like butter, jam, and a cup of coffee for your toast): - a starting value stored in a variable, sometimes called a counter - a stopping value which evaluates to a boolean (true or false; we talked about booleans last time) - a statement which is executed on every loop, usually to [[p5js-week-03#reassigning_variables_and_incrementing|increment]] the variable with the starting value/counter In the __curly braces__, you put the things that you want to happen on each loop. Remember, the loop is going to run until the stopping value is false. In the for loop above, notice these things: - the starting value is 0, and it's stored in the variable called i - the stopping value is 10 - the third value which is the result of the [[p5js-week-03#reassigning_variables_and_incrementing|incrementing]] operator ++ What this means is that the [[p5js-week-03#for-loop|for-loop]] will start the variable i at 0 and increase it by 1 every time. It will continue to run as long as i is less than 10. Also notice that the variable i is used in the body of the [[p5js-week-03#for-loop|for-loop]] in the call of console.log. ==== conditions in a for-loop ==== There are some details about the conditions for the for loop that we should think about. The first item in the conditions is the [[p5js-week-03#the_parts_of_a_for-loop|counter]]. The first point to be careful about is using the let statement. We'll talk about "let" more in the future. For now, you should know that "let" is a JavaScript keyword, like "function" or "if", that makes variables safer to use. If you forget to use "let", it's going to be easy for a particular kind of bug to happen in your program. A bug is, according to Wikipedia, "... an error, flaw or fault in a computer program or system that causes it to produce an incorrect or unexpected result, or to behave in unintended ways." The second point is that the name of the variable that we use as a [[p5js-week-03#the_parts_of_a_for-loop|counter]] in the [[p5js-week-03#for-loop|for-loop]] is up to you to choose. Just like you can name arguments "banana" or "chocolate", you can also name the [[p5js-week-03#the_parts_of_a_for-loop|counter]] in the [[p5js-week-03#for-loop|for-loop]] anything you want. However, it's very common for programmers to call the [[p5js-week-03#the_parts_of_a_for-loop|counter]] "i", which can represent the ideas of "integer" or "index" or "iteration". Personally, I think that 'iteration' is the most useful to think about for a [[p5js-week-03#for-loop|for-loop]]. The Oxford Dictionary defines "iteration" as "repetition of a mathematical or computational procedure applied to the result of a previous application". In that case, the i means which repetition or time we are at. The third point is that we can then use this [[p5js-week-03#the_parts_of_a_for-loop|counter]] variable inside the [[p5js-week-03#for-loop|for-loop]] any way we want. In this function, we are going to collect numbers in a variable and then add the value of i to it on each loop. Notice how i increases, and then the value of the numberCollector variable also increases. function buildNumber (n) { let numberCollector = 0; for (let i = 0; i < n; i++) { console.log("hi! this is the value of i: " + i); numberCollector = numberCollector + i console.log("The current value of the numberCollector is " + numberCollector) } console.log("The final value of the numberCollector is " + numberCollector) return numberCollector } Now call buildNumber and see what happens: buildNumber(5) The fourth point is that you can start the [[p5js-week-03#the_parts_of_a_for-loop|counter]] of the [[p5js-week-03#for-loop|for-loop]] at any value you want, but it's customary to start at 0. Just so that you can see how it works, let's start a for loop at a different value. Notice that it works the same as 0; we just have to be careful about setting the stopping point. The n argument still controls how many times we loop, but also notice that the value of i is different from our old repeater function. function repeaterFrom10 (n) { for (let i = 10; i < n+10; i++) { console.log("hi! " + i) } } Call it like this: repeaterFrom10(10) As always, be careful about the syntax: put the conditions of the [[p5js-week-03#for-loop|for-loop]] in __parentheses__ first, and then the body of the [[p5js-week-03#for-loop|for-loop]] in __curly brackets__. ===== for-loops and return statements ===== You have to be careful about where you put the return statement. If the return is inside the body of the [[p5js-week-03#for-loop|for-loop]], the loop will stop as soon as the return is evaluated. That means if you do some computation and then return the result, the loop stops immediately! It's like stopping the toaster before our bread is toasted. The following function does that. Even when you ask it to loop 1,000 times, it stops on the very first loop. function returnsWrong (n) { let numberCollector = 0; for (let i = 0; i < n; i++) { console.log("adding this to the numberCollector: " + i); numberCollector = numberCollector + i; return numberCollector } } Try it: returnsWrong(1000) The key is to put the return statement after the [[p5js-week-03#for-loop|for-loop]], like this: function returnsRight (n) { let numberCollector = 0; for (let i = 0; i < n; i++) { console.log("adding this to the numberCollector: " + i); numberCollector = numberCollector + i; } return numberCollector } Try this one: returnsRight(1000) There's another kind of mistake that some are making with the conditions in the [[p5js-week-03#for-loop|for-loop]]. Have a look at this wrong function: function wordPrinter (word1, n) { for (let b = 0; b < n; i++) { console.log(word1 + b) } return (word1) } Here, the conditions for the [[p5js-week-03#for-loop|for-loop]] are wrong. The conditions of the [[p5js-week-03#for-loop|for-loop]] can be found in the __parentheses__ after "for". In this case, it's: for (let b = 0; b < n; i++) // this is wrong! Remember what the three parts mean: - starting point - stopping point - how to [[p5js-week-03#reassigning_variables_and_incrementing|increment]] That means that in this case, the count is measured with b. However, b is not [[p5js-week-03#reassigning_variables_and_incrementing|incremented]]. Only i is [[p5js-week-03#reassigning_variables_and_incrementing|incremented]]. "i" will continue to go up, but this increasing value is never used later in the function. Maybe it's more important to notice that this means that the loop will never stop. Eventually it will crash the computer! Don't do this! The conditions should be like this: for (let b = 0; b < n; b++) It's OK to use b, i, cherries, or any other variable we want; we just have to be sure that the same one is used for all three parts. If we want a traditional [[p5js-week-03#the_parts_of_a_for-loop|counter]] for our [[p5js-week-03#for-loop|for-loop]]. i is usually the best choice because people are used to it. for (let i = 0; i < n; i++) ===== p5js ===== {{:colored-toast-flat-lay-symmetry-jam.jpg?600|}} (photo from https://www.piqsels.com/en/public-domain-photo-zkfbs) OK, now let's try to use what we've learned for drawing in p5js. - using a [[p5js-week-03#for-loop|for-loop]] to gradually change colors - filling the screen with earths using our earth function - learning the remainder operator to get even more earths on the screen - filling the screen with your rainbow toast ==== using a for-loop to gradually change colors ==== Look at this example. We'll use a [[p5js-week-03#for-loop|for-loop]] to increase the value of a variable, like we talked about above. Notice that we increase the toastRed variable, and we decrease the toastBlue variable. ==== many earths with our earth function and a for-loop ==== Last time we put many earths on the screen, we had to write out our earth function call several times. One of the cool things about programming is that we can let the computer do the boring work like that for us. Let's use a [[p5js-week-03#for-loop|for-loop]] to do it instead. Look at lines 17-19. ==== filling the screen with earths using a for-loop and the remainder operator ==== That [[p5js-week-03#for-loop|for-loop]] only gives us one row of earths. What if we want to fill the whole screen? To do that, let's learn another tool: the [[p5js-week-03#filling_the_screen_with_earths_using_a_for-loop_and_the_remainder_operator|remainder operator]]. It's the % sign. An operator is a symbol we put between two items to do something to them, like + - * and /. Try this in the console: 4%2 The percent sign (%) in JavaScript is the remainder operator. The remainder is the amount that is left over after you divide one integer by another. When you divide 4 by 2, there's nothing left, so it returns 0. How about this one? 5%2 With five divided by two, the remainder is one. And this one? 6%2 What about this one? 7%2 By now, I think you can guess this one... 8%2 We can use it to produce a looping series of numbers (or to keep numbers within a certain range) when we have another number that is increasing or decreasing. In this code, we use the [[p5js-week-03#filling_the_screen_with_earths_using_a_for-loop_and_the_remainder_operator|remainder operator]] and Math.floor to get several rows of earths. Study this code and see if you can figure out how it works. ==== filling the screen with your rainbow toast ==== OK, you've learned a lot today. Now it's time for a more serious challenge. Can you fill your screen with your rainbow toast? Try to use the things that we've learned above to fill the screen with rainbow toast just like we did with the earth. After you've finished that, then try to fill the screen with your wolves, robots, or flowers! Share your work with the class on your wiki page and screenshots in our chat rooms. We want to see what kind of art you've coded!