From the course: Python Practice: Real-World Coding Challenges

Laying out the code

- [Instructor] In Python, I can print a dot. There you go. Okay, well that's not very exciting, but by using a for loop, for i in range (0,20), I can make this dot draw a diagonal line. So, let's do a Space times i plus our dot. Hey, look at that. Now, if I import the time package, I can slow this dot down a little bit. So, after I draw the dot, I'm going to call time.sleep and we're going to sleep for a 10th of a second. So, now we get diagonal line going slowly across the screen. Now, let me import the OS package. What I can do with this, is I can actually clear the terminal, just get rid of everything on the terminal and start from scratch. So, I'm going to make a function called clear, and I'm going to call os.system cls if os.name is equal to nt. So, this is the command that we're going to send to the system, if our operating system is Windows NT, because it's a little bit different, else we're going to just call clear. Now, I'm going to sleep for a 10th of a second, then clear the screen. I'm also going to add a few new lines up here, just to sort of bump this down on the page, and make it look nice. Hey, look at that. We have a dot moving horizontally across the screen. It's an animation. So, let's take this principle of printing, sleeping, and then clearing the screen, and think about how we would make sort of a terminal drawing program, or as I like to call it a terminal scribe. This terminal scribe will draw images across the screen, and we'll be able to control where it draws them with a Cartesian coordinate system, where 00 is the top left corner of the screen, the Y-axis increases as you go down, and the X-axis increases as you go to the right. This coordinate system might seem a little strange at first but it's common in situations where you're working with positions on top of documents. For instance, HTML and CSS have this reversed Y-axis, as does most photo editing software, where the boundaries of a box are defined with 00 in the top left and larger numbers at the bottom right. So, first I'm going to define a canvas class. This is what our terminal scribe will draw on. The terminal scribe itself is like the pen that moves around and draws on the canvas. So, say def init, self, width and height, so the canvas knows how big it is. I'm going to call width and height, self._x and self._y, and I'm using the underscore here, just to indicate that they are internal variables, and shouldn't be accessed outside of the canvas class. Then our canvas needs to have some sort of estate, something that can be drawn on. Which cells are colored in and which are blank? So, let's make this a list of lists. So, this is like a matrix, so, it's going to be blank for y in range self._y, then outside of this for x in range self._x. So, we have a nested list comprehension here, and that makes a matrix. Whoops, self._canvas. Okay, so now let's make a handy function, or a method that can draw on the cells in the canvas. Let's call this setPos, for set position Let's pass in the position and a mark, self._canvas position, whoops, 0, position one is equal to our mark. So, this function updates the element at position 0,1 and then sets it to the character or the mark that gets passed in. Okay, so we're going to go back to the canvas later, but for now, let's take a look at the terminal scribe. So, the terminal scribe will take in a canvas class that it's supposed to draw on. Self and then canvas, so it knows what it's supposed to be drawing on. Canvas is equal to canvas, and I'm also going to give it a position, and just set that to the default 0,0. So, it's going to start at the top left corner of the screen. Now, I'm going to give it two other variables, mark and trail. I'm going to set mark equal to an asterisk, and this mark is the ascii character that gets printed to the canvas at the scribe's current location, and then trail is going to be the trail that drags along behind it and creates that line. Alright, so now let's start writing up some functions. So, first is going to be draw. This will move our scribe from the current position. So, self.pos to the new position that gets passed in. So, the first thing we want to do is set the old position on the canvas to our trail character. So, self.canvas.setPos, and we're going to use the current position, and then set it to that trail. Then we're going to update the position self.canvas.setPos, It's actually going to be very similar, but instead of trail we're going to use the mark. Okay, now it would be really handy if we had some sort of a print function on the canvas at this point that printed the current state of the canvas to the terminal. So, I'm just going to add this placeholder on here, .print, and then let's do it. Okay, so the first thing we're going to do is call self.clear. Then for y in range self._y, we're going to print that row. So, print.join, we're going to join that row. Col y, whoops, for col in self._canvas. Okay, let's also bring in that clear function that we made earlier. Get rid of that. Let's add that as a method on the canvas, and indent everything there. Pass in self. So, self.clear rate, we're printing, and then our terminal scribe is also calling print. All right, so now let's see how it works. Let's try it out. Canvas is equal to a new canvas. Let's make it 20 by 20, and then our scribe is equal to terminal scribe and pass in that canvas. Then, for i and range 0 through 10, for j and range 0 through 10. Scribe.draw i,j. All right, let's see how it works. So, I'm going to go and make a few little tweaks to this, add some comments and get it ready for our first challenge. If you're feeling a little bit lost, don't worry, I'm starting you from square one, literally. All we're doing in the next challenge is adding a little code at the bottom here to make it draw a square. You're going to do great.

Contents