Try-except, Indexerror, Alternatives to fix the error

Asked

Viewed 104 times

1

I’ve got a college job to do, in a way I finished it, but with a few tricks I wanted to set up and make the code less confusing and so on.

Operation of the programme:

Basically it creates a 600x400 screen with a x number of balls (this number is passed by parameter of the function of creates the balls) walking around the window, when they hit the edges they take another trajectory so that always stay on the screen.

Explanation of functions:

  • criaBola: Puts the information as tag, x, y and vertical/horizontal acceleration;

  • criaBolas: When the program is started it spreads the balls randomly across the screen, throughout the program this function is used to make the balls walk around the screen;

  • verificaBolasArea: Checks if where it was clicked with the mouse there is a ball, if it exists returns the index of the list;

  • removeBola: Erases the ball from the screen, this function is used both to make the balls walk so much to 'burst' them;

  • moveBola: This is the heart of the program, makes the balls change direction, passes the index of the list to the other functions, etc;

Part I need help:

In function moveBola I needed to put a Try-except for IndexError, what happened is when I started the program everything worked perfectly, I clicked on some balls and they were popping as predicted, but whenever I arrived at the last ball the program gave error "Indexerror: list index out of range"; This error also happened time and again with the other balls without being the last. This was the only way I could make the program run without error, but I was wondering if there are more alternatives to how to solve this type of problem.

from Tkinter import *
import random, time

largura = 600
altura = 400
diametro = 50
bola = ['', 0, 0, 0, 0]
bolas = []



def randPos():
    pos = [0,0]
    pos[0] = random.randint(1, (largura - diametro))
    pos[1] = random.randint(1, (altura - diametro))
    return pos


def randCor():
    R = random.randint(100, 255)
    G = random.randint(100, 255)
    B = random.randint(100, 255)
    cor = '#%02x%02x%02x' % (R,G,B)
    return cor


def criaBola(id, novaBola):
    if novaBola == True:
        posr = randPos()
        bolas[id][1] = posr[0]
        bolas[id][2] = posr[1]
    tela.create_oval(bolas[id][1], bolas[id][2], bolas[id][1] + diametro, bolas[id][2] + diametro, fill=randCor(), tags=bolas[id][0])
    tela.update()
    print 'bola[index:{}]'.format(bolas.index(bolas[id])),bolas[id][0], randCor(), "POS: X:{} Y:{}".format(bolas[id][1], bolas[id][2])

def criaBolas(quantidade):
    for n in range(quantidade):
        print "CRIA BOLAS INDICE N ", n
        bola[0] = ('bola{}'.format(n))
        bola[3] = 10
        bola[4] = 10
        bolas.append(bola[:])
        print bolas
        criaBola(n, True)
    print(bolas)

def removeBola(idBolaList, idBolaTela):
    print "REMOVENDO BOLA[{}]".format(idBolaTela)
    print type(idBolaList)
    if idBolaList == 999:
        print 'REMOVENDO BOLA PARA ATUALIZACAO DE COORDENADAS'
    else:
        print "PRINTANDO BOLA A SER APAGADA IDBOLALIST", idBolaList, idBolaTela
        bolas.pop(idBolaList)
    tela.delete(idBolaTela)

t = Tk()
tela = Canvas(t, width=largura, height=altura)
tela.pack()

def verificaBolasArea(px1, py1):
    for ii in range(len(bolas)):
        if (bolas[ii][1] <= px1) and (px1 <= (bolas[ii][1]+diametro)) and (bolas[ii][2] <= py1) and (py1 <= (bolas[ii][2] + diametro)):
            print 'O mouse clicou dentro da bola\nA bola[{}] esta nas coordenadas ({},{}) - (X,Y)'.format(bolas[ii][0],bolas[ii][1], bolas[ii][2])
            r = [bolas.index(bolas[ii]), bolas[ii][0]]
            return r
        else:
            print 'bola nao encontrada'

def motion(event):
    print 'tamanho lista:',len(bolas)
    mx, my = event.x, event.y
    r = verificaBolasArea(mx, my)
    removeBola(r[0], r[1])
    print "--->uma bola foi removida", bolas
    print('{}, {}'.format(mx, my))
t.bind('<ButtonRelease-1>', motion)

def encerra(event):
    t.destroy()
t.bind('<ButtonRelease-3>', encerra)


def attPos(id):
    print "ATTPOS ID PASSADO ",id, bolas[id][0]
    print bolas
    bolas[id][1] += bolas[id][3]
    bolas[id][2] += bolas[id][4]

def moveBola(idBola = []):
    i=0
    while i>-1:
        try:
            while i<=len(bolas):
                print "WHILE I MOVE BOLAS:" ,i
                index = idBola.index(idBola[i])
                if ((bolas[i][1]+diametro) > largura) or (bolas[i][1] < 0):
                    bolas[i][3] *= -1
                if ((bolas[i][2]+diametro) > altura) or (bolas[i][2] < 0):
                    bolas[i][4] *= -1
                time.sleep(0.0299)
                tela.update()
                print "******************",index
                print len(bolas), bolas, index
                removeBola(999, idBola[i][0])
                attPos(index)
                criaBola(index, False)
                i+=1
                if i == len(bolas):
                    i=0
        except IndexError:
            if len(bolas) <= 0:
                i=-1
                tela.create_text(largura / 2, altura /2, text="PARANBENS! VOCE ESTOUROU TODAS AS BOLAS.\nClique com o botao direito do mouse para fechar o programa.", font=("Arial Black", "12"), tags='Fim', fill='red')
            else:
                i=0
            print len(bolas)*100

criaBolas(10)
moveBola(bolas)

t.mainloop()
  • Needless to say, it’s a college job, it doesn’t help. Get to the point.

1 answer

1

The len returns a value starting from 1, not 0. However, the counting of positions starts from 0.

while i<=len(bolas):

Let’s assume that the len(bolas) is equal to 10: The positions of the balls are 0 to 9, which closes 10 numbers (value of Len), i starts at 0 and goes up to 10 (because while i<=len(bolas)), however, the array does not go up to position 10, but up to 9.

I believe that exchange while i<=len(bolas): for while i<len(bolas): will solve your problem, thus not needing Try/except.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.