Reputation: 29
I'm writing a program to choose a random line from a text file using a while loop as a counter and then another variable to choose the random line:
import random
fortunes_file = open("fortunes.txt", "r")
fortunes = fortunes_file.readline()
count = 0
while fortunes != "":
count += 1
fortunes = fortunes_file.readline()
rand_line = random.randint(1, count)
print fortunes[rand_line]
fortunes_file.close()
However, I get the following error when trying to run the program:
IndexError: string index out of range
Upvotes: 0
Views: 51
Reputation: 149971
You're overwriting fortunes
on each iteration of the while
loop.
At the EOF .readline()
returns an empty string, therefore fortunes[rand_line]
raises the IndexError
. You could use .readlines()
instead (or just use the file object as an iterator):
with open("fortunes.txt", "r") as fortunes_file:
fortunes = fortunes_file.readlines() # alternatively, use list(fortunes_file)
print(random.choice(fortunes))
Upvotes: 1
Reputation: 22292
The problem is here:
fortunes = fortunes_file.readline()
...
fortunes = fortunes_file.readline()
You just re-defined the variable, so after that while
loop end, fortunes
actually is the last line in your file.
You can simply use io.IOBase.readlines()
to read the file into a list line-by-line, and use random.choice()
to choose an element in a list randomly. You don't need a counter and slice the list yourself.
For example:
import random
# use `with` is recommended here since you don't need close the file manually
with open("fortunes.txt", "r") as f:
fortunes = fortunes_file.readlinse()
print random.choice(fortunes)
However, if you also want to know how to fix your code, just put the output of io.IOBase.readline()
into a list like below:
import random
fortunes_file = open("fortunes.txt", "r")
fortunes = []
fortunes.append(fortunes_file.readline())
count = 0
while fortunes != "":
count += 1
fortunes.append(fortunes_file.readline())
rand_line = random.randint(1, count)
print fortunes[rand_line]
fortunes_file.close()
Note that if you don't want use .readlines()
and random.choice()
, you still don't need that counter, you can also use len(fortunes)
to get the length of your list instead of write a useless counter yourself.
Upvotes: 0
Reputation: 174662
You need readlines()
not readline()
; but actually you can highly simplify your code:
import random
with open('fortunes.txt') as f:
fortunes = list(f)
print(random.choice(fortunes))
Or, if you prefer the readlines()
version:
import random
f = open('fortunes.txt')
fortunes = f.readlines()
f.close()
print(random.choice(fortunes))
Upvotes: 2