简体   繁体   中英

IndexError: string index out of range for reading first line in a file python

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

It looks like line[0] doesn't exist, ie 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...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM