Вопрос или проблема
Я установил проект беспилотного автомобиля с сайта superdatascience, когда я открываю карту через терминал, через какое-то время окно карты закрывается или оно закрывается сразу после того, как я увеличиваю окно карты, и выдает мне эту ошибку:
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "map.py", line 235, in <module>
CarApp().run()
File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 826, in run
runTouchApp()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 502, in runTouchApp
EventLoop.window.mainloop()
File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 727, in mainloop
self._mainloop()
File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 460, in _mainloop
EventLoop.idle()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 340, in idle
self.dispatch_input()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 325, in dispatch_input
post_dispatch_input(*pop(0))
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 231, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "/usr/lib/python2.7/dist-packages/kivy/core/window/__init__.py", line 1360, in on_motion
self.dispatch('on_touch_down', me)
File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "/usr/lib/python2.7/dist-packages/kivy/core/window/__init__.py", line 1376, in on_touch_down
if w.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 460, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "map.py", line 181, in on_touch_down
sand[int(touch.x),int(touch.y)] = 1
IndexError: index 620 is out of bounds for axis 1 with size 600
Код, который у меня есть в мозге (файл ai.py)
class Dqn():
def select_action(self, state):
probs = F.softmax(self.model(Variable(state, volatile = True))*100) # T=100
action = probs.multinomial(num_samples=1)
return action.data[0,0]
Код, который у меня есть в карте (файл map.py)
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
global length, n_points, last_x, last_y
with self.canvas:
Color(0.8,0.7,0)
d = 10.
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 10)
last_x = int(touch.x)
last_y = int(touch.y)
n_points = 0
length = 0
sand[int(touch.x),int(touch.y)] = 1
Что мне сделать или изменить??
Одно из значений, возвращаемых touch.x
или touch.y
, больше размеров массива sand
.
Вы можете попробовать добавить блок try/except вокруг этого и вывести полезное сообщение – просто в качестве примера, так как я не имею понятия, что эта программа делает (в функции on_touch_down
):
def on_touch_down(self, touch)
...
...
try:
sand[int(touch.x), int(touch.y)] = 1
except IndexError:
print("Touchdown did not occur within the end-zone! No goal!")
Ответ или решение
Обработка исключений в программировании важна, чтобы предотвратить возможные сбои в работе программы и предоставлять пользователю информативные сообщения об ошибках. В вашей ситуации, как показывает трассировка стека, проблема заключается в неверно обработанных координатах прикосновений со стороны пользователя, что приводит к попытке обращения к несуществующему индексу массива sand
.
Теоретическая часть
Ошибка IndexError: index 620 is out of bounds for axis 1 with size 600
указывает на то, что попытка доступа к элементу с индексом 620 происходит в массиве, который имеет размеры только до 599 по соответствующей оси. Такая ошибка возникает, когда в программе есть несоответствие между ожидаемыми и фактическими размерами данных, к которым производится доступ.
Один из наиболее распространённых источников подобных ошибок — это неверная обработка данных о размерах окна, пользовательского ввода или данных из других частей программы. В вашей ситуации проблема может быть связана с размерностью массива sand
, которая не соответствует граничным условиям в графическом интерфейсе Kivy
.
Пример: понимание проблемы
В предоставленном вами коде функция on_touch_down
из класса MyPaintWidget
обрабатывает события прикосновений на графическом интерфейсе. Однако, действия, которые производятся в этой функции, не учитывают пределы массива sand
. Код пытается присвоить значение в массиве sand
на позициях, которые передаются с координатами прикосновения touch.x
и touch.y
. Допустим, что ширина и высота вашего окна или холста составляет 600×600 пикселей, а массив sand
имеет те же размеры; в случае, когда координата прикосновения touch.x
или touch.y
превышает соответствующий размер массива, происходит ошибка.
Практическое применение: решение проблемы
Чтобы избежать этой ошибки, необходимо убедиться, что координаты прикосновений всегда находятся в диапазоне массива sand
. Это делается путём добавления проверки перед доступом к элементам массива:
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
global length, n_points, last_x, last_y
with self.canvas:
Color(0.8,0.7,0)
d = 10.
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 10)
last_x = int(touch.x)
last_y = int(touch.y)
n_points = 0
length = 0
if (0 <= int(touch.x) < sand.shape[0]) and (0 <= int(touch.y) < sand.shape[1]):
sand[int(touch.x), int(touch.y)] = 1
else:
print("Координаты прикосновения выходят за пределы массива.")
В этом коде мы добавляем условную проверку, чтобы убедиться, что touch.x
и touch.y
находятся в пределах размеров массива sand
. Это предотвратит возникновение IndexError
и позволит вам легко отследить, происходят ли прикосновения вне допустимого диапазона массива.
Кроме того, для более надежного и понятного кода, стоит рассмотреть использование именованных констант или методов для определения ограничений массива и холста, чтобы не допускать жёстко заданные значения, которые могут быть сложны для поддержания и изменения.
Таким образом, правильно обрабатывая события прикосновений и управляя координатами в зависимости от размеров массива, можно устранить ошибку IndexError
и улучшить стабилизацию работы программы. В дополнение к обработке ошибок, такой подход способствует написанию более структурированного и поддерживаемого кода.