1

A smaller piece of a program I'm writing finds points neighboring a point as if it were on a grid. Observe the cave drawing ...

grid illustration

The program works just fine with positive numbers -- output mockup:

Point: (5, 5) -
(4, 4), (5, 4), (6, 4), (4, 5), (6, 5) ...

and so on ... but let's see what happens if I try a negative value:

Point: (-3, 2) -
ACTUAL OUTPUT ↓ Below is debug
['-3', '2']
-4
1
-4
3
-3
2
-2
1
-2
3

And the error:

Traceback (most recent call last):
  File "C:\Users\jojaw\Documents\All\Stuff\Junk\Python\Continent generation-0.2fork.py", line 193, in <module>
    res = pf.neighbors_point((command[0], command[1]), (0, 0, 50, 50))
  File "C:\Users\jojaw\Documents\All\Stuff\Junk\Python\Continent generation-0.2fork.py", line 51, in neighbors_point
    for j in neighbors[i]:
IndexError: list index out of range

Code:

def neighbors_point(self, pt, bds): #pt is a two-element tuple, bds is a four-element tuple
    neighbors = []
    for x in range(-1, 2): # range excludes last number, actual range is [-1, 0, 1]
        for y in range(-1, 2): # range excludes last number, actual range is [-1, 0, 1]
            neighbors.append((pt[0]+x, pt[1]+y))
    for i in range(0, len(neighbors)): #debug code
        for j in neighbors[i]:
            print(j)
        #end debug code
        condition = neighbors[i][0] < bds[0] or neighbors[i][0] > bds[2] or neighbors[i][1] < bds[1] or neighbors[i][1] > bds[3]
        if condition:
            neighbors.pop(i)
    neighbors.pop(4)
    return neighbors

So, what's my screwup?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 2
    The problem is in the line where you pop array elements inside of the loop that iterates over your array. The loop starts with a range 0 to 9, but when the `condition` evaluates to true, you remove an element from the array, thus reducing the array size. – Dakshraj Sharma Jul 02 '21 at 18:32
  • @DakshrajSharma I think I understand, what should I do instead? `for i in neighbors`? –  Jul 02 '21 at 18:46
  • @JoJodaMan Please read: https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating – VPfB Jul 02 '21 at 18:52
  • Why do you `pop` values at all? – mkrieger1 Jul 02 '21 at 19:29

1 Answers1

0

That's because you are removing elements using neighbors.pop(i) if condition else continue. You might remove the following lines:

for j in neighbors[i]:
    print(j)

Or you can use try and except in order to catch the error:

try:
    for j in neighbors[i]:
        print(j)

except IndexError as error:
    print(error)

Finally, you might use two separate lists, one for iteration and one for popping values out.

Samir Ahmane
  • 830
  • 7
  • 22
  • 1
    Used a list-iter loop eg `for i in list` -- to avoid out-of \-range issues -- and a counter to keep track of index of element I wanted to remove. Your solution helped. I'll check it! –  Jul 02 '21 at 20:25