Hi, welcome to the second lesson on this final project, which is a complex systems project, where we're actually using a grid data structure in an object-oriented style as well as Langton's ants walking on top of it. Some interesting ideas here for the final project. Let's just continue working on the script that we started from last session. Here we are. Let's just remind ourselves we have a grid class. As you can see here, this grid class takes the arguments of columns and rows and the size of the screen to basically distribute the appropriate number of cells and that distributes the entirety of that screen. We want to have a class that would cover the entirety of the screen and is able to hold some data. We're not using this variable yet, the data variable. As you can see, we can actually draw the grid completely without any data. Let's just create some functions to store some data first and then display that data. We're going to see later in future videos how a new entity will be able to manipulate or use that data for their own behavior. Let's just start by creating a function here in the data in the grid data class. It's going to be the definition of init data. This function, we want to run only at the very beginning of the script. We need to do it only once, and this will be a way of potentially randomizing or deciding that some entities in the grid actually have one kind of data versus a different kind of data. We're only going to work with a Boolean data or a zero and one number, and that should be enough for our algorithm to really be able to take some decisions. We're going to write a for loop. We're going to actually copy paste the for loop. I really like copy pasting parts of my code. If you want to do that, this is what you would do. We want to do nested for loop once more. Within a loop, for i in range for columns and for j in range for the number of rows. Here, we are going to use the random function. I don't think we have imported random in this script. Remember that in this case, Python classes operate a separate file. This particular class, if it's going to make use of the random module, we want to make that available to this particular script. The number, this is a variable that's going to be an integer. We could say it's going to be random.randint zero and one. It's a random integer between zero and one. At this point, we could do self.data.append the number. What are we doing here? This is the first time we are actually using this list that we stored. Within this list, we're going to store a bit of data, either a zero or a one, based on this random function. We are initiating this data. We are going to call this function only once, make it that we calculate the randomization of the data, and then we're going to be able to display it. At this point, we want to check if this function is running. We are going to call this function init_data, but we need to call it from within the grid. We're going to call this function separately because the run function, we are ultimately run it every frame in the draw loop. But for now, we are going to call the initialized data and then the execution of the display. Let's see if we have any errors at this point. I don't think we have errors, but we cannot see the data. The data is just some zero and one store within this list. If we want to render that [inaudible], we would actually have to associate that data or establish some relationship between the display and the data that we generated. This is why we actually created the data in the same fashion that the grid because if we actually do it this way, we will know that we have exactly the exact number of data points as we have grid rectangles or grid cells. This is going to be useful because we could actually now equate each one of these entities of data to one of the cells in the grid. Let's just do that. Let's just improve our display function so that it would display. If an entity has a value of zero, we're going to paint it black. If it has a value of one, we're going to paint it white. In order to do so, we would need to know if I would give or request the value of a particular entry point and the data, I would need to do some calculation. We're actually going to do a helper function that is going to help us calculate if we provide an x and a y how do we access the data point that is equivalent to that. Let's just create a function of get_data. We're going to do self, x, and y. Think of this as a way of saying, hey, from the grid I want the zero, zero, meaning the index 0 in x and y. But because the data is distributed as a single list, we are trying to convert what we would call a form of grid notation of columns and rows positions to a flat notation. The result of this function will be the index of the piece of data we're looking for. Here, I will write a small formula that I've used many times in the past, and it's actually really useful. We're going to do the absolute, first of all. We definitely want to make sure that we are working with the absolute. Let's just add a few parentheses here just because there's going to be a lot of different entities here, so y times self.rows. That's the first entity. We're going to divide that by self.screen_height. Then this is going to be multiplied by self.columns plus, and here again we're going to do parentheses. We're going to organize this a little bit once we have it written. Let's just do self. Here we go. I think there's [inaudible] What are we doing here? This function might seem quite difficult. If you imagine like a grid, you're basically trying to say, well, I know that the list of data is all spread into one single sequence, and we need to be able to calculate just given particular x and y, 0, 0 or let's say 10 and 1, the second row in the 10th column. We need to be able to start spreading up that data. You do so by calculating how many rows have you gone in and multiplying by the number of columns and then adding the final bit that you're missing, which is the addition. This function will be incredibly handy to return. We're going to do something that I don't think we have done before, but you probably covered it in the first specialization, which is how functions can return a variable. We're going to do self.data index. We are using this index to access the data within our grid. Think about the following. We're using the get_data function. We're going to give an x and y, let's say 5 and 5, and it's going to be returning us what is the data stored in that cell. This function is going to be incredibly useful. It's one of those functions that once you have it written once, you can copy paste it again and reuse it in different projects because it's a function that helps you convert the notation from an x and y, like two coordinate system to a singular list index. What are we doing with this function now? We actually would like to change the way these rectangles are displayed. The only thing that is missing is using this function. We could say if. Let's use our function self.get_data. If we check this function and we use the value of i times rec_size, which is this is the x coordinate given this coordinate, and given the j coordinate would be j times basically what we're spelling out here, basically the same information. This is the x coordinate and the y coordinate. Given these coordinates, if this coordinate is zero, meaning that the data inside that cell is zero, we are going to paint this rectangle black. Let's just make that statement saying fill is zero and then else fill is 255. Now we can actually remove this two. The only really difference between these two scenarios is that if the data is zero, if its else would be a one, we're going to paint the ones as white. Let's see. We have this result, which is, as you can see, the data has been randomized. We are using a random function to initially store data zero or a one inside each cell. It's not technically inside, but the class contains a list that we are equating and we have a way of retrieving the data inside each one of the cell entities. We're doing so with this function get_data, which we can provide an x and y coordinate, and it will tell us within the cell, it's in fact that's a zero or that's a one. We're going to leave this video here. We actually have the grid working as intended. Again, I like doing this test if this data would in fact work for more units. Let's just double a little bit the number here. As you can see, our randomization of data as a class and as an object in a way are working well. Let's just do that and here we go. We're going to leave it here. In the next video, we're going to start seeing how a new class, an ant class, can actually start operating on top of this grid and taking behaviors based on the data that we created. I'll see you in the next video.