Hi. Welcome to this new lesson. We are going to start constructing a drawing class this time using the knowledge that we have from classes. We're going to be combining some of the information and the knowledge that we have from Week 3, where we are actually using a gradient rectangle to move across the screen. We're going to start constructing a class that can actually do those things and see how we can actually use classes to make this behavior part of the class. Let's jump into the code. This is where we left off. We have 200 instances of a class running in a loop. What I would like to start doing is reducing this number to something a little bit more manageable, something like 20 or even something like five. Let's see if that should work. It's a very low resolution. That's fine. That's just going to make it a little bit more visible to us. We'll go through the process of as you prototype. As you prototype a class like this one, you might want to do certain changes to the class structure, to the class data. We would actually see how we could actually convert a design that we did outside a class structure, or something that we did without a class structure and convert it into a class. We're going to start adapting the class for it to have the functionality that we had with our gradient rectangle. We need to create a few variables. A variable that is going to be a self.r, self.g, and a self.b. These are going to stand for the internal RGB colors that we will manipulate. We will also include, if you remember the rate of change, the rate of change of red, the rate of change of green, and the rate of change of blue. Self.r_change and let's just create three versions of that for the other attributes RGB. These values here, we might not need to include them in the constructors, because they're going to be values that we will use to manipulate the color value. We could decide we're going to start with this color, but this color is going to change. But the change is something that we want to change. Let's just do r_change here and assign it here, g_change. If you want to have less variables, this could have been done with vectors, as well. If you think about it, you could actually have one vector that has three values and just use the r_change being the x component of the vector, the y component could be g, and the z component could be b. But we're doing it explicitly with different variables. The R color will be the color.r, the green information and the blue information. Just double checking the documentation here. What we actually need is to invoke the red command for the color. The red is going to give us the red channel being the first attribute of that color, the green attribute of that color, and the blue attribute of that color. Still, if we try to run this at this point, we will run into an error because we have basically requested this class to have a lot more information than before. Whenever we try to run this, we won't be providing these three attributes. Let's just put some placeholder values for now into our attributes. We could say that the rate of change for the first value is going to be one, the next one is going to be one, and the next one is going to be one. The rate of change, we will use to see how much change of color we will have every frame in each one of those different channels, the change for red, the change for green, and change for blue. But right now, we're just providing those placeholder values in order to make sure that we are satisfying the new constructor we have. We've added a lot more data here. Let's see. Let's see what we are having an issue here with. We need to specify what we are doing. The rate of change is going to be r, g and b. Let's see. Now things are working again. We have those new attributes working, but obviously, they're not changing. They're not creating any gradient. But we actually have the values that we could use for a new function. If you remember a little bit, if you go back into our previous session, we can actually create a variable here or a function here. Let's do it before the display. To calculate the actual RGB values of the gradient. Let's call it a calculate gradient. The gradient uses the r += r_change. The red color, whatever it is, will start kind of gradually increasing at a rate of one per frame. Let's do the same thing for g. and b. All of this as the values go from zero being black and 255 being white, we would gradually tend to white. What we will be missing in this calculation would be to bounce the values once they reach 255 or the maximum numeric value within the color spectrum, bounce back and starts moving to zero and then bounce back again. It's something that we've done again outside a class structure, but we're seeing how would we do it within the class. Now we're actually ready to use, instead of fill(self.color) we could actually do fill(r, g, b) because we have those explicit values that are being pre calculated here. We can use those. We need to just make sure that we're using the calculate gradient function, which is a new function here. X.calculate_gradient. We first calculate the gradient, then we display the rectangle, and then we move. We're having an error. Let's just go and find where that error is. We need to use self dot, kind of move too quickly here, self.b and same here. This is kind of some of the challenges of the class to remembering what is internal attributes to the class so that we could actually make sure that we're using those across different functions. Let's just make sure that those are all internal attributes of the class that we're manipulating throughout. We're still having an issue. Let's just keep digging and see what it is. Let's see if we don't calculate the gradient. We can identify that the error is certainly within that function. If we don't invoke that function, we do not run into the error. It could be that we're having an issue with this color. Let's just start with zero. We'll come back to this a minute ago. But I think that it's possible that what we're actually getting from that calculation is not a number. That doesn't seem to be a problem. I see it. Here calculate gradient, we were missing the self. You can see here, it actually looks quite interesting when we're doing it with black and white. Let's just bring back the definition of red that we had here. Green and blue. It's working. All the values are increasing, but once they get to white, they remain there. I guess I'm moving a bit too quickly through the material of the class construction. Let's make sure that we have access to all the self and all the internal variables before we use them that internally can trouble, as you could see. Let's create as we've done before, the bouncing effect, meaning that the color when it reaches the maximum value, so if the color red, if(slef.r < 0), let's just make the slef.r_change* times=-1.8, so let's just make sure that we type that correctly, if the red color is smaller than zero, we flip or multiply it by minus one. The change which is going plus one is going to become negative one. Let's just make also the attribute of, want to copy those things two times, so r,g and b and g_change and b_change. This is not really happening yet because we're actually moving upwards, so what we actually want to do is a condition that is meant for the upper boundary, which is bigger than 255, basically we do the same thing. We multiply that by minus one. The rate of change is a value that starts at one when it reaches its maximum boundary will become minus one or its negative number. That's why we're multiplying it by minus one. Another that we have that template, we can actually copy paste it for each one of the three conditions r,g and b, and making sure we're doing that right for each one of the variables. This is what we have constructed already in Week 3 within the vector class and now we're actually rewriting it as a class so that we can reuse it for a series of multiple rectangles. Think that all my statements are missing the column. There we go. As you can see here, all these entities get to white or close to white, and they start bouncing back towards black, and so on. All of them, depending on the speed of movement will be doing this gradient shift and that's certainly very different from what we had before and it's certainly working. If we like the rate of change of each class, if you remember, we actually use a placeholder number here, the rate of change for this number, it's one for all of them. We could use the same equation here, and you can manipulate the numbers. I mean these scripts are actually very open for you to play with these parameters. This is going to have so much possibility for transforming the speed of, let's say you want the rate of change in some cases to be faster, maybe could be a 5, 3, there's no right or wrong here, it's really an invitation to experiment of how these different parameters actually affect the transformation of these graphics. As you can see here, this rectangle is moving very slowly, but changing color very quickly, so you're actually getting this pattern at a different rate. This one is moving a lot quicker, so it's really giving us a way of composing with this algorithm that it's every time that we run it, it's quite different. It's actually based on randomness in many ways, but it's actually trying to calibrate that the random colors that are appear in certain sequences in a way that we actually can manipulate. Again, you can actually increase the number of colors as we've done before to something like 20. As you can see, all of the rectangles here are all changing color. This shows you really the power of classes and instances. Well, in Week 3, we were actually constructing one single script for making one of these rectangles move around. In this lesson, we're actually learning how do we can actually encapsulate that into the package of a class. Then we can actually deploy 20,100 objects, all of them behaving with the pattern of this gradient rectangle. Hopefully, you're actually understanding how we can actually use object oriented programming for design and how we can actually deploy and create really beautiful patterns by instancing objects that behave in a very unique way. I'm going to continue discussing how we can actually work with different files and how we're going to structure our code a bit further and really wrap up our understanding of classes in the next session. I'll see you then.