why do i keep getting a index error: string index out of range

Viewed 44

I'm trying to create a leaderboard for my game and every time my game ends am supposed to display the leaderboard. however, I keep getting this error and I don't know where to proceed. the score is supposed to stored on the leaderboard but that is not happening.

main file:

# importing package
import turtle
import random 
import sys
import time
import leaderboard as lb





# set the background color of the turtle screen
backround = turtle.Screen()
backround.bgcolor("forest green")
backround.tracer(False)
backround.setup(600,8000)

#score configureation
score = 0
leader_names_list = []
leader_scores_list = []
leaderboard_file_name = "a122_leaderboard.txt"
player_name = input ("Please enter your name:")


#variables 
style = ('Comic Sans MS', 18, 'bold')


#display score


scorewriter = turtle.Turtle()
scorewriter.hideturtle()
scorewriter.penup()
scorewriter.goto(-170, 180)
scorewriter.pendown()
scorewriter.showturtle()





#create net
net = turtle.Turtle()
net.color("white")
net.hideturtle()
net.pensize(15)
net.penup()
net.goto(-250,375)
net.pendown()
net.goto(250,375)
net.goto(250,175)
net.penup()
net.goto(-250,375)
net.pendown()
net.goto(-250,175)

#create goalie
goal = []
backround.addshape("goal.gif")
goalie = turtle.Turtle()
goalie.speed(7)
goal.append(goalie)
goalie.shape("goal.gif")
goalie.penup()
goalie.goto(0,210)
goalie.setheading(270)

#create Soccer Ball
ball = []
backround.addshape("soccer.gif")
sb = turtle.Turtle()
sb.speed(7)
ball.append(sb)
sb.shape("soccer.gif")
sb.penup()
sb.goto(130,0)
sb.setheading(90)


#create goal line
goal_line = []
gl = turtle.Turtle() 
goal_line.append(gl)
gl.shape("square")  
gl.penup()
gl.goto(0,180)
gl.shapesize(1,25,1)
gl.hideturtle()

#create left boundary
left_boundary = []
lbnd = turtle.Turtle() 
left_boundary.append(lb)
lbnd.shape("square")  
lbnd.penup()
lbnd.goto(-250,-90)
lbnd.shapesize(30,1,1)
lbnd.hideturtle()

#create right boundary
right_boundary = []
rb = turtle.Turtle() 
right_boundary.append(rb)
rb.shape("square")  
rb.penup()
rb.goto(250,-90)
rb.shapesize(30,1,1)
rb.hideturtle()

#Create left button
lbutton = turtle.Turtle()

lbutton.shape('circle')
lbutton.fillcolor('red')
lbutton.shapesize(5)
lbutton.penup()
lbutton.goto(-200, -200)

#create middle button
mbutton = turtle.Turtle()

mbutton.shape('circle')
mbutton.fillcolor('red')
mbutton.shapesize(5)
mbutton.penup()
mbutton.goto(0, -200)

#create right button
rbutton = turtle.Turtle()

rbutton.shape('circle')
rbutton.fillcolor('red')
rbutton.shapesize(5)
rbutton.penup()
rbutton.goto(200, -200)

#create text
t = turtle.Turtle()
t.hideturtle()

t.penup()
t.goto(-200,-275)
t.pendown()
t.write('Dribble Left!', font=style, align='center')
t.penup()
t.goto(0,-275)
t.pendown()
t.write('Shoot Straight!', font=style, align='center')
t.penup()
t.goto(200,-275)
t.pendown()
t.write('Dribble Right!', font=style, align='center')

#end tracer
backround.update()
backround.tracer(True)

#functions 
def update_score_for_frog():
    global score
    score =  score +1
    scorewriter.clear()
    scorewriter.write(score, font = style)   

def manage_leaderboard():
  global leader_scores_list
  global leader_names_list
  global score
  lb.load_leaderboard(leaderboard_file_name, leader_names_list, leader_scores_list)
  if (len(leader_scores_list) < 5 or score > leader_scores_list[4]):
    lb.update_leaderboard(leaderboard_file_name, leader_names_list, leader_scores_list, player_name, score)
    lb.draw_leaderboard(leader_names_list, leader_scores_list, True, score)
  
  else:
    lb.draw_leaderboard(leader_names_list, leader_scores_list, False, score) 

def GoalieMovement(x, y):
    n = random.randint(1,3)
    if n == 1:
        goalie.goto(-200,210)
    if n == 2:
        goalie.goto(0,210)
    if n == 3:
        goalie.goto(200,210)
     
def left(x,y):
    leftb()
    GoalieMovement(x,y)
    sb.setheading(180)
    sb.forward(30)
    scorekeeper()

def straight(x, y):

    GoalieMovement(x,y)
    sb.setheading(90)
    sb.forward(30)
    scorekeeper()

def right(x, y):
    rightb()
    GoalieMovement(x,y)
    sb.setheading(0)
    sb.forward(30)
    scorekeeper()

#create boundary functions  
def leftb():
    if ((lbnd.xcor() + (sb.xcor())) == -420 ):
        wtxt = turtle.Turtle()
        wtxt.hideturtle()
        wtxt.speed(0)
        wtxt.penup()
        wtxt.goto(0,100)
        wtxt.pendown()
        wtxt.write('Out of Bounds!', font=style, align='center')
        wtxt.penup()
        wtxt.goto(0,0)
        wtxt.pendown()
        wtxt.write('GAME OVER!', font=style, align='center')
        time.sleep(5)
        sys.exit()
        
def rightb():
    if (((rb.xcor()) + (sb.xcor())) == 650):
        wtxt = turtle.Turtle()
        wtxt.hideturtle()
        wtxt.speed(0)
        wtxt.penup()
        wtxt.goto(0,100)
        wtxt.pendown()
        wtxt.write('Out Of Bounds!', font=style, align='center')
        wtxt.penup()
        wtxt.goto(0,0)
        wtxt.pendown()
        wtxt.write('GAME OVER!', font=style, align='center')
        time.sleep(5)
        sys.exit()

def scorekeeper():
    if ((abs(goalie.ycor()) - abs(sb.ycor())) < 35 ) and ((abs(goalie.xcor()) - abs(sb.xcor())) < 35 ) :
        wtxt = turtle.Turtle()
        wtxt.hideturtle()
        wtxt.speed(0)
        wtxt.penup()
        wtxt.goto(0,100)
        wtxt.pendown()
        wtxt.write('Saved By The Keeper!', font=style, align='center')
        wtxt.penup()
        wtxt.goto(0,0)
        wtxt.pendown()
        wtxt.write('GAME OVER!', font=style, align='center')
        time.sleep(5)
        wtxt.hideturtle()
        scorewriter.hideturtle()
        sb.hideturtle()
        goalie.hideturtle()
        net.hideturtle()
        gl.hideturtle()
        lbutton.hideturtle()
        mbutton.hideturtle()
        rbutton.hideturtle()
        t.hideturtle()
        manage_leaderboard()
        time.sleep(2)
        sys.exit()
    if ((abs(gl.ycor()) - abs(sb.ycor())) < 10 ):
        sb.goto(130,0)
        goalie.goto(0,210)
        update_score_for_frog()
""" 
        qtxt = turtle.Turtle()
        qtxt.hideturtle()
        qtxt.penup()
        qtxt.speed(0)
        qtxt.goto(0,100)
        qtxt.pendown()
        qtxt.write('Goal!', font=style, align='center')
"""
#create clickable buttons
lbutton.onclick(left)
mbutton.onclick(straight)
rbutton.onclick(right)



#screen
wn = turtle.Screen()
wn.mainloop()

Leaderboard file:

def load_leaderboard(file_name, leader_names, leader_scores):

  leaderboard_file = open(file_name, "r")  
  
  for line in leaderboard_file:
    leader_name = ""
    leader_score = ""  
    index = 0
    

    while (line[index] != ","):
      leader_name = leader_name + line[index] 
      index = index + 1
      print("leader name is:", leader_name)

    leader_name.append(leader_name)
    
    while (line[index] != "\n"):
      print(leader_score)
    
    leader_score.append(int(leader_score))

    leaderboard_file.close()


def update_leaderboard(file_name, leader_names, leader_scores, player_name, player_score):

  leader_index = 0
  while (leader_index < len(leader_scores)):

    if (player_score >= leader_scores[leader_index]):
      break
    else:
      leader_index = leader_index + 1
  
  leader_scores.insert(leader_index, player_score)
  leader_names.insert(leader_index, player_name)

  print("leader_names are:", leader_names)
  print("leader_scores are:", leader_scores)

  if (len(leader_names) == 6):
    leader_names.pop()
  if (len(leader_scores) == 6):
    leader_scores.pop()
  
  leaderboard_file = open(file_name, "w")  
  leader_index = 0
  
  
  while (leader_index < len(leader_names)):
    leaderboard_file.write(leader_names[leader_index] + "," + str(leader_scores       [leader_index]) + "\n") 
    leader_index = leader_index + 1
  
  leaderboard_file.close()
  

def draw_leaderboard(leader_names, leader_scores, high_scorer, turtle_object, player_score):
  
  font_setup = ("Arial", 20, "normal")
  turtle_object.clear()
  turtle_object.penup()
  turtle_object.goto(-200,100)
  turtle_object.hideturtle()
  turtle_object.down()
  leader_index = 0

  while leader_index < len(leader_names):
    turtle_object.write(str(leader_index + 1) + "\t" + leader_names[leader_index] + "\t" + str(leader_scores[leader_index]), font=font_setup)
    turtle_object.penup()
    turtle_object.goto(-200,int(turtle_object.ycor())-50)
    turtle_object.down()
    leader_index = leader_index + 1

  if (high_scorer):
    turtle_object.write("Congratulations! You made the leaderboard!", font=font_setup)
  else:
    turtle_object.write("Sorry, you didn't make the leaderboard. Maybe next time!", font=font_setup)

  turtle_object.penup()
  turtle_object.goto(-200,int(turtle_object.ycor())-50)
  turtle_object.pendown()

error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/turtle.py", line 617, in eventfun
    fun(x, y)
  File "/Users/Final.py", line 200, in straight
    scorekeeper()
  File "/Users/Final.py", line 266, in scorekeeper
    manage_leaderboard()
  File "/Users/Final.py", line 171, in manage_leaderboard
    lb.load_leaderboard(leaderboard_file_name, leader_names_list, leader_scores_list)
  File "/Users/leaderboard.py", line 11, in load_leaderboard
    while (line[index] != ","):
IndexError: string index out of range

the problem seems to be isolated to the load_leaderboard function but I cannot get the index error to go away

1 Answers

Your code is likely breaking because some of the lines in the a122_leaderboard.txt file do not have commas.

When the leaderboard file doesn't have commas in some lines the index variable would be growing indefinitely until it is larger than len(line) - 1 and after that an exception would be thrown:

  while (line[index] != ","):
     leader_name = leader_name + line[index] 
     index = index + 1
     print("leader name is:", leader_name)

one way to fix this is to change the code by adding additional check for the index variable to make sure it isn't growing beyond the size of the line:

while (line[index] != ",") and (index < len(index)):
     leader_name = leader_name + line[index] 
     index = index + 1
     print("leader name is:", leader_name)

this change should fix this specific error, but keep in mind that you might need to change some other parts of your code as well to make sure it is working.

Related