Battleship 7/19 and 8/19 BUG?


In part 7 (Hide…) we are told to write these functions:

def random_row(board_in):
return randint(0, len(board_in) - 1)

def random_col(board_in):
return randint(0, len(board_in) - 1)

But in the next part(…and Seek!), the random_col function goes from:

def random_col(board_in):
return randint(0, len(board_in) - 1)


def random_col(board_in):
return randint(0, len(board_in[0]) - 1)

Where did that ZERO come from and why??? Im so confused!! Is it a bug or is it that Codecademy just forgot to explain to us why they suddenly put the ZERO there and what purpose it has?


The zero is the index of row one (top row). If the board is not square, we need to be sure we take the length of the row into account (column count), not the length of the board (row count).

  1. So basically Codecademy forgot to tell us why they put it there. Why didnt they tell us to put the zero there in part 7, but suddenly they put it in in part 8 of the lesson with no explanation?

2.But isnt the board squared already…? They made us make it 5x5 earlier…

3.I seriously dont get it! I mean I get that the zero means the first index in the row , but after that Im not sure whats going on…what does the zero do? why is it there?


As stated earlier, it is the index of the first row. The board does not HAVE to be square.


But they already told us to make it squared…so isnt it squared? I mean thats why we made it squared with the for loop in one of the earlier parts of the lesseon??


The instructions ask for a square board, but that doesn’t preclude us from playing with the code once we finish the exercises.


So if I was to remove the zero, the board will be squared right? But if i let the zero stay inside the function, I can later change the size of the board just by putting in random number inside the squared-brackets where the zero is right now…is that what you are trying to say?


They might not have bothered to tell you to include it in 7/19, because for the purposes of the exercises so far your board has been square (5 x 5). Assuming you’ve followed the instructions, your number of rows given by len(board) is equal to the number of columns, given by len(board[0]).

I think perhaps Codecademy simply made an assumption, and neglected to point out why they made the change they did to the code in 8/19. Basically, using board[0] allows you to accommodate a non-square board if you choose but the exercises instruct you to use 5 x 5.

Yes, they did. However, your code shouldn’t assume that the board will always be square, which brings us to…

Think about how you’re generating, and storing, the layout of the board. It’s basically a list of lists.

Your variable, board, is a list generated by the loop:

for x in range(0, 5):
  board.append(["0"] * 5)

In that code, the ["0"] * 5 bit gives you a row that’s 5 items long - i.e. we create 5 columns. If we used 7 instead of 5, we’d no longer get a square board from the loop above.

The number of rows you make is based on the upper value you give to the range function.

So, let’s say we do this:

for x in range(0, 10):
  board.append(["0"] * 7)

then board[0] will contain ["0", "0", "0", "0", "0", "0", "0"], or one complete row. If you know the length of the row (i.e. the length of board[0]) you know the number of columns. Since each item in board itself is a complete row, if you know the length of board you know the number of rows.

Does that make it any clearer?


The zero doesn’t affect the size of your board at all. :slight_smile:

The size of your board is determined by the loop that generates it:

for x in range(0, A):
  board.append(["0"] * B)

where you need to swap A for the number of rows, and B for the number of columns, that you want the board to have.


The board would be considered square. Changing that number will only change which row it takes the length from.


So, I get that for x in range(0, A) will give the amount of rows I tell it to give me…
…and that board.append([“0”] * B) will give me the amount of columns i tell it to give me…
So if A = 7, I’ll get 7 rows…
If B = 4, I’ll get 4 columns…

So it willl look like this:


And I get that (0, len(board_in) - 1), in the random_row fucntion, in our situation with the 5x5 board…means:

(0, 5-1) = (0-4), and 0-4 is the lenght of the row which is basically 5 "O"s, because we count from 0 to 4:

Index: 0 1 2 3 4
Count:1 2 3 4 5

But, I still dont get the (0, len(board_in[0]) - 1) inside the random_col function!!

print len(board)       # 7
print len(board[0])    # 4


I get that len(board) is 7

But I dont see how len(board[0]) is 4…I see it as 1, because index 0 means 1, so 1 column…
And if we use the code from the lesson (0, len(board[0]) - 1), I see it as (0, 1-1) = (0, 0)…


No, it’s most certainly not one. board[0] returns the contents of that index, which is not 1 but is the list representing the row.

If we start with an empty board

board = []

we can add a row by using:

board.append(["0"] * 5)

so now print board looks like this in the console output:

[['0', '0', '0', '0', '0']]

See how there are two sets of square brackets? This means that the list ['0', '0', '0', '0', '0'] is sat within another list.

The outer square brackets represent the board list. The inner square brackets (['0', '0', '0', '0', '0']) are another list, sat at the first index of board. So, len(board[0]) works out the length of the item in the first position of the board list; or, works out the length of ['0', '0', '0', '0', '0'].

Do you now see why board[0] is used to calculate the number of columns, and why it’s not 1?

>>> board = []
>>> board.append(["0"] * 5)
>>> print(board)
[['0', '0', '0', '0', '0']]
>>> print(board[0])
['0', '0', '0', '0', '0']
>>> len(board[0])

def make_board(height, width):
    return [['O'] * width for x in range(height)]
def print_board(grid):
	print ('\n'.join([' '.join(x) for x in grid]))


random_row will be in the range [0…6].

random_col will be in the range [0…3].


Ok, so len(board[0]) is telling us to look at list number one of five lists(that we told the for loop to put inside the board-list). That one list, which is represented by index 0 inside (board[0]) contains 5 “O”…? Now what?


I get how we give number of rows and their lenght(columns) with the for loop…its this function that I dont get:

def random_col(board_in):
return randint(0, len(board_in[0]) - 1)


If that one list contains five O's, how can the length of that list object be 1?


Ok so it has 5 elements ("O"s)…and we have 4 more lists like that inside the board-list…

If we put 1 instead of 0, is the same thing…5 "O"s…and…


You need to choose a random column that is within the confines of the board.

board_in allows you to pass in your board to the function.

randint will return a random number between the range that you give it. Let’s run with the 5 x 5 board the exercise gets you to create. board_in[0] will be ['0','0','0','0','0'], so len(board_in[0]) is 5. Each of those 0's is a column on your board, right?

If we just use randint(0, len(board_in[0])), which will evaluate the same as randint(0,5) there’s a chance the result will be 5.

There’s only 5 items in our list, with indexes 0 to 4, so we need to correct the upper limit for randint by subtracting 1 from the length of the list.


def random_col(board_in):
  return randint(0, len(board_in[0]) - 1)

uses the length of the row to calculate the number of columns in the board, and return a number that equates to a valid index in your row list (which is ['0','0','0','0','0']).