Two-dimensional arrays
Rows and columns: the depth grid as a list of lists.
Do this lesson in the simulatorSome data comes in rows and columns: a spreadsheet, a game board, a seating plan. BugBot's depth sensor is one of these. It sees an 8 by 8 grid of distances, like a very low-resolution picture where every pixel is a distance instead of a colour. A list of lists stores rows and columns, and exams call it a two-dimensional array.
A list of lists
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
board = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(board[0]) # the first row
print(board[1][2]) # row 1, column 2
board[2][0] = 0 # change one item
print(board)
print(len(board), "rows of", len(board[0]))
Each item of board is itself a list: a row. board[1] is the second row, and board[1][2] is the item in column 2 of that row, which is 6. Read the two indexes as row, then column.
Visiting every item
Two indexes need two loops, one inside the other:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for row in range(len(board)):
for col in range(len(board[row])):
print(board[row][col], end=" ")
print()
total = 0
for row in board:
for item in row:
total = total + item
print("total", total)
The first pair of loops uses indexes, the second uses the items directly. Both visit all nine.
The depth grid
tof_grid() gives the sensor's 64 distances as one flat list, row after row. Row 0 is the top of the view and row 7 the bottom; column 0 is the left and column 7 the right. Rows 2 and 3 look level, straight ahead. Turning the flat list into rows is a good use of what you know:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
flat = tof_grid()
grid = []
for r in range(8):
grid.append(flat[r * 8 : r * 8 + 8])
for row in grid:
print(row)
print("straight ahead, level:", grid[3][3], "and", grid[3][4])
Look at the printout. The top rows see over everything, so they read the sensor's maximum. The level rows see the box, off to one side. The bottom rows see the mat just in front of the robot, so they are small and steady.
Finding something in the grid
To steer, you want the nearest reading in the level rows and which column it is in:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
flat = tof_grid()
grid = []
for r in range(8):
grid.append(flat[r * 8 : r * 8 + 8])
best = 999
best_col = 0
for r in [2, 3]:
for c in range(8):
if grid[r][c] < best:
best = grid[r][c]
best_col = c
print(f"nearest: {best} cm in column {best_col}")
This is the largest-so-far pattern from lesson F2.7, turned round to find the smallest, over two dimensions. best starts impossibly large so the first reading replaces it.
Task: nearest column
There is a box off to one side. Without moving, find the smallest reading in the level rows (2 and 3) of the depth grid and print nearest: <cm> cm in column <n>.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
flat = tof_grid()
best = min(flat)
print("nearest:", best)
Challenges
- Print the grid with every reading over 100 shown as
--, so the shape of the box stands out. - Work out the average of each column in the level rows, and say which side of the robot is more crowded.
- Make a 3 by 3 noughts and crosses board of
".", put anXin the middle, and print it as three lines.