Up: Program Design

Neighbors

slide 01 Welcome to the fifth episode of the Software Carpentry lecture on program design using invasion percolation as an example. In this episode, we’ll take a look at how we find the neighbors of a cell.
slide 02 If you recall, we need to find the neighbors of cells that have already been marked as being filled with pollution.
slide 03 Those cells have been given the value -1.
slide 04 The blue cell shown here is a neighbor of the filled region if any of the green cells have already been given the value -1.
slide 05 Those cells have coordinates that are +1 or -1 on either the X or the Y axis from the coordinates of the blue cell.
slide 06 We’re not looking at the cells that are on the diagonals, at (x-1, y+1) and so forth.
slide 07 We should check the science on this, but again, it’s a simplifying assumption that’s safe to make in the first version of our program.
slide 08 Here’s a piece of code that tests to see whether a cell is a candidate for being filled in. This version is buggy. For x in range(N), and for y in range(N), if the cell to our left is filled, or the cell to our right is filled, or the cell below us is filled, or the cell above us is filled, then this cell is a candidate for filling.
slide 09 This code is buggy because it doesn’t take into account what happens at the edges.
slide 10 If we take x equals 0 and subtract 1, we get an X coordinate of -1. In Python, that means the last cell in the row. That will wrap around to the far edge, which is definitely not what we want.
slide 11 The situation on the other border is even worse. If we’re at the right-hand edge, and we add one to the X coordinate, we actually fall off the end of the list and get an out-of-bounds exception.
slide 12 Here’s another version of the code that tests for this. For x in range(N), for y in range(N), if x is greater than 0, i.e., if we’re not on the left edge, then we check to see if the cell to our left is filled. If it is, then this cell is a candidate for filling. We then repeat this double test for each of the other directions.
slide 13 The problem with this is that it means a lot of repeated code, and code that is repeated in two or more places will eventually be wrong in at least one.
slide 14 Here’s a third version that’s good enough for production. We’re going to combine the two tests in each direction using an and. So, if x is greater than 0 and the cell to our left is filled, or if x is less than N-1 and the cell to our right is filled, and so forth, then this cell is a candidate for filling.
slide 15 Why does this work? Well, the first half of each test checks to make sure that the second half can safely be run. If we are not on the left edge…
slide 16 …then we can take a look to the left to see if that cell is filled.
slide 17 and in Python (and in most other modern programming languages) does short-circuit evaluation—it only tests the second part if the first part is true.
slide 18 This is the general pattern. When you need to do a sanity check before you can safely execute some other test, the idiom is “If sanity check and some other test”. The and ensures that if the sanity check fails, i.e., if it is False, then the other test is never even executed, because as soon as and knows that one side is False, it doesn’t need to test the other, because False and anything is False.
slide 19

  1. No comments yet.
  1. No trackbacks yet.