0

Hello im writing code that opens a file. it reads the file and does specific tasks if the line currently being read in the file contains content which marks to a task.

the first thing I am trying to do, is read the first line and add it to a running score and then move on with the file. However, i am encountering the error: indexError: string index out of range.

which I just dont understand I feel like that shouldn't be happening.

so heres the code that is referenced by the error. Followed by the actual error. Then followed by the full code for context.

    def processScores( file, score):
#opens file using with method, reads each line with a for loop. If content in line
#agrees with parameters in  if statements, executes code in if statment. Otherwise, ignores line    

    with open(file,'r') as f:
        for line in f:  #starts for loop for all if statements
            line = line.strip()
            if line[0].isdigit():
                start = int(line.strip())
                score.initialScore(start) #checks if first line is a number if it is adds it to intial score

The error

   processScores('theText.txt',score)
Grabing intial score from file, inital score set to 50
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    processScores('theText.txt',score)
  File "C:/Users/christopher/Desktop/hw2.py", line 49, in processScores
    if line[0].isdigit():
IndexError: string index out of range

The total code

    class Score:
# class to hold a running score, from object to parameter
# also to set number of scores that contribute to total of 1

    def __init__(self):
#initalizes the running score and score input accumilators
        self.runScore = 0
        self.scoreInputs = 0

    def initialScore(self, start):
#takes the initial score in line one of the file and updates
#the running score to the inital score
        self.runScore += start
        print('Grabing intial score from file, inital score set to ' + str(start))


    def updateOne (self, amount):
#updates running score by amount and Score input by 1
        self.runScore += amount
        self.scoreInputs += 1
        print('Adding ' + str(amount) + ' to score, number of scores increased by 1. Current number of points scored ' + str(self.runScore) + ',  current number of scores at ' + str(self.scoreInputs))

    def updateMany(self,lst):
#updates running score by the sum of the list and score inputs by the amount of
# number of items in the list
        self.runScore += sum(lst)
        self.scoreInputs += len(lst)
        print('Adding the sum of ' + str(len(lst)) + 'scores to score. Score increased by ' +  str(sum(lst)) + '. current number of points scored ' + str(self.runScore) + ', current number of scores at ' + str(self.scoreInputs)) 

    def get(self):
#returns the current score based on total amount scored
        print('Grabbing current score')
        print(self.runScore)

    def average(self):
#returns the average of the scores that have contributed to the total socre
        print('calculating average score')
        print(self.runScore // self.scoreInputs)

score = Score() # initize connection       

def processScores( file, score):
#opens file using with method, reads each line with a for loop. If content in line
#agrees with parameters in  if statements, executes code in if statment. Otherwise, ignores line    

    with open(file,'r') as f:
        for line in f:  #starts for loop for all if statements
            line = line.strip()
            if line[0].isdigit():
                start = int(line.strip())
                score.initialScore(start) #checks if first line is a number if it is adds it to intial score

            elif line == 'o' or line == 'O':
                amount = int(next(f))
                score.updateOne(amount) #if line contains single score marker, Takes content in next line and
                                        #inserts it into updateOne
            elif line == 'm'or line == 'M':
                scoreList = next(f)
                lst = []
                for item in scoreList: 
                    lst.append(item)
                    score.updateMany(lst) # if line contains list score marker, creates scoreList variable and places the next line into  that variable
                                          #  creates lst variable and sets it to an empty list
                                          # goes through the next line with the for loop and appends each item in the next line to the empty list
                                          # then inserts newly populated lst into updateMany

            elif line == 'X':
                score.get(self)
                score.average(self) # if line contains terminator marker. prints total score and the average of the scores.
                                    # because the file was opened with the 'with' method. the file closes after 

What the file looks like

50

O

30

O

40

M

10 20 30

o

5

m

1 2 3

X

With the code I can see that the file is reading the first line you can see that with the print statement before the code fails.

processScores('theText.txt',score)

Grabing intial score from file, inital score set to 50

that print statement is running on this line of code

def initialScore(self, start):
#takes the initial score in line one of the file and updates
#the running score to the inital score
        self.runScore += start
        print('Grabing intial score from file, inital score set to ' +  str(start))

So I am to assume that it is moving on to the next part of the code. but I am not sure.

Thank you all very much

2
  • What is the file you're trying to process? Commented Jan 18, 2015 at 2:52
  • hi @Th3Cuber I have edited my question to give you better information on the file and the code thank you very much for looking into this. The edits are near the bottom after the total code Commented Jan 18, 2015 at 3:00

2 Answers 2

1

It looks like line[0] doesn't exist, i.e. line is empty so you can't read the first character of it. Most likely your file is empty or you have a blank line at the end of the file. To debug, you can check each line by doing something like print line or print len(line). You may also want to add some checking to your code to ensure that you don't try and process empty lines, such as if line: or if line.strip():, which will evaluate to True if there are characters remaining in the line after white space has been stripped from the start and end of the line.

Edit: In your case you'd want something like:

with open(file,'r') as f:
    for line in f:
        # strip white space
        line = line.strip()
        # if line is not empty
        if line:
            if line[0].isdigit():
                # do this
            elif line == 'o'
                # do that
            # etc...
Sign up to request clarification or add additional context in comments.

7 Comments

hi @figs I have edited my question to give you better information on the file and the code thank you very much for looking into this. The edits are near the bottom after the total code
Yes, if every second line is empty then that would explain your error.
oh man!! I didnt even take that into consiteration..... lame.. so now I must make an elif statement accounting for a blank line haha. This sucks of course its something right in my face that I wasnt looking at
You shouldn't need an elif for your blank lines, just ignore them. I updated my answer with an example...
thanks @figs yeah i was thinking about how I was going to do that. Appreciate your input
|
0

Your line contains empty string after strip() as @figs advice, simply change to this:

...
if line and line[0].isdigit():
    start = int(line)

And you don't need to repeat strip() twice.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.