index out of range raises in random function [duplicate] - python

This question already has answers here:
f.read coming up empty
(5 answers)
Closed 7 years ago.
I have this function which simply opens a text files and read lines:
def select_word(model):
lines = model.read().splitlines()
selectedline = random.choice(lines)
return [selectedline.split(":")[0],selectedline.split(":")[1]]
when I call this function for just one, there is no problem. But when I call it more than once:
print select_word(a)
print select_word(a)
print select_word(a)
print select_word(a)
print select_word(a)
I got this error:
Traceback (most recent call last):
File "wordselect.py", line 58, in <module>
print select_word("noun")
File "wordselect.py", line 19, in select_word
selectedline = random.choice(lines)
File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 275, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
What is the problem with that function?

import random
def select_word(model):
with open(model, 'r') as f:
lines = f.read().splitlines()
selectedline = random.choice(lines)
return [selectedline.split(":")[0],selectedline.split(":")[1]]
result = select_word('example.txt')
print result
I did this and didnt get a problem.
just make sure that in the file you are opening you have something like.
Line: 1
Line: 2

random.choice raises IndexError if you pass it an empty sequence. This happens when you call .read() on a file object the second time (you can only do it once, subsequent calls will return an empty string).
To fix the function, you could read the file once then pass the lines to the function, e.g.:
lines = list(model)
def select_word(lines):
selectedline = random.choice(lines)
return selectedline.split(":", 1)

File handles operate like generators. Once you have read a file, you have reached the end of stream.
model.seek(0) # bring cursor to start of file after reading, at 2nd line of the function

Related

Why we can't print particular line of text file with this method? [duplicate]

The main function that the code should do is to open a file and get the median. This is my code:
def medianStrat(lst):
count = 0
test = []
for line in lst:
test += line.split()
for i in lst:
count = count +1
if count % 2 == 0:
x = count//2
y = lst[x]
z = lst[x-1]
median = (y + z)/2
return median
if count %2 == 1:
x = (count-1)//2
return lst[x] # Where the problem persists
def main():
lst = open(input("Input file name: "), "r")
print(medianStrat(lst))
Here is the error I get:
Traceback (most recent call last):
File "C:/Users/honte_000/PycharmProjects/Comp Sci/2015/2015/storelocation.py", line 30, in <module>
main()
File "C:/Users/honte_000/PycharmProjects/Comp Sci/2015/2015/storelocation.py", line 28, in main
print(medianStrat(lst))
File "C:/Users/honte_000/PycharmProjects/Comp Sci/2015/2015/storelocation.py", line 24, in medianStrat
return lst[x]
TypeError: '_io.TextIOWrapper' object is not subscriptable
I know lst[x] is causing this problem but not too sure how to solve this one.
So what could be the solution to this problem or what could be done instead to make the code work?
You can't index (__getitem__) a _io.TextIOWrapper object. What you can do is work with a list of lines. Try this in your code:
lst = open(input("Input file name: "), "r").readlines()
Also, you aren't closing the file object, this would be better:
with open(input("Input file name: ", "r") as lst:
print(medianStrat(lst.readlines()))
with ensures that file get closed.
basic error my end, sharing in case anyone else finds it useful. Difference between datatypes is really important! just because it looks like JSON doesn't mean it is JSON - I ended up on this answer, learning this the hard way.
Opening the IO Stream needs to be converted using the python json.load method, before it is a dict data type, otherwise it is still a string. Now it is in a dict it can be brought into a dataFrame.
def load_json(): # this function loads json and returns it as a dataframe
with open("1lumen.com.json", "r") as io_str:
data = json.load(io_str)
df = pd.DataFrame.from_dict(data)
logging.info(df.columns.tolist())
return(df)

Why my python code is showing value error?

I am writing this python code to check DNA sequence file. The output will be the name of person to whom this DNA is matched.
This link has the description of assignment.
https://cs50.harvard.edu/x/2020/psets/6/dna/
But when i try to run the code its showing value error.
Kindly someone let me know the error in the code.
I am new to the programming.
from sys import argv, exit
import csv
def max_Reptitions_of_substrings(dnaSequences , substring):
arr = [0] * len(dnaSequences)
for i in range(len(dnaSequences) - len(substring), -1, -1):
if dnaSequences[i: i + len(substring)] == substring:
if i + len(substring) > len(dnaSequences) - 1:
arr[i] = 1
else:
arr[i] = 1 + arr[i + len(substring)]
return max(arr)
def print_Matching(reading, newdata):
for i in reading:
human = i[0]
value = [int(digit) for digit in i[1:]]
if value == newdata:
print(human)
return
print("No match")
def main():
if len(argv) != 3:
print("Missing Command line Argument")
exit(1)
with open(argv[1], 'r') as database:
reading = csv.reader(database)
sequences = next(reading)[1:]
with open(argv[2], 'r') as sequenceFilestrong text:
dnaSequences = sequenceFile.read()
newdata = [max_Reptitions_of_substrings(dnaSequences, substr) for substr in sequences]
print_Matching(reading, newdata)
Value error shown is as
Traceback (most recent call last):
File "dna.py", line 36, in <module>
print_Matching(reading, newdata)
File "dna.py", line 15, in print_Matching
for i in reading:
ValueError: I/O operation on closed file.
The error message is pretty explicit and spot-on:
ValueError: I/O operation on closed file.
You are opening your CSV file in a with block and create a new CSV reader based on that file. But at the end of the with block, the file is closed. reading now refers to a CSV reader that’s linked to a closed file connection.
Hence the error.
Try to look at code indentation, it's very important in Python. First with should be inside function main, second with should be inside first with.
Why?
Just look at the code. In print matching you're using reading csv.reader, which right now try to use already closed file passed as argument.

Python: I'm getting an error saying that the list index in out of range, when isn't [duplicate]

I'm writing a simple script that is trying to extract the first element from the second column of a .txt input file.
import sys
if (len(sys.argv) > 1):
f = open(sys.argv[1], "r");
print "file opened";
line = [];
for line in f:
line = line.strip("\n ' '")
line = line.split(",")
print line[1]
f.close();
My input file looks like this:
Client 192.168.1.13 said ``ACC: d0bb38f18da536aff7b455264eba2f1e35dd976f,389182.567,-0.042,-0.893,0.333''
Client 192.168.1.13 said ``ACC: d0bb38f18da536aff7b455264eba2f1e35dd976f,389182.590,-0.036,-0.905,0.273''
Client 192.168.1.13 said ``ACC: d0bb38f18da536aff7b455264eba2f1e35dd976f,389182.611,-0.046,-0.948,0.204''
Client 192.168.1.13 said ``ACC: d0bb38f18da536aff7b455264eba2f1e35dd976f,389182.631,-0.074,-0.978,0.170''
Client 192.168.1.13 said ``ACC: d0bb38f18da536aff7b455264eba2f1e35dd976f,389182.654,-0.100,-1.006,0.171''
I want my delimiter to be a comma. When I print the length of the line out, I'm getting 5 elements (as expected). However, whenever I try to index the list to extract the data (i.e., when I call print line[1]), I keep getting the following error:
file opened
Traceback (most recent call last):
File "stats.py", line 13, in <module>
print line[1]
IndexError: list index out of range
I don't understand why it's out of range when clearly it isn't.
I would guess you have a blank line somewhere in your file. If it runs through the data and then generates the exception the blank line will be at the end of your file.
Please insert
print len(line), line
before your
print line[1]
as a check to verify if this is the case.
You can always use this construct to test for blank lines and only process/print non-blank lines:
for line in f:
line = line.strip()
if line:
# process/print line further
When you are working with list and trying to get value at particular index, it is always safe to see in index is in the range
if len(list_of_elements) > index:
print list_of_elements[index]
See:
>>> list_of_elements = [1, 2, 3, 4]
>>> len(list_of_elements)
4
>>> list_of_elements[1]
2
>>> list_of_elements[4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>>
Now you have to find out why your list did not contain as many elements as you expected
Solution:
import sys
if (len(sys.argv) > 1):
f = open(sys.argv[1], "r")
print "file opened"
for line in f:
line = line.strip().strip('\n')
# Ensure that you are not working on empty line
if line:
data = line.split(",")
# Ensure that index is not out of range
if len(data) > 1: print data[1]
f.close()
you probably have empty line(s) after your data, I ran your test code without them it worked as expected.
$ python t.py t.txt
file opened
389182.567
389182.590
389182.611
389182.631
389182.654
if you don't want to remove them, then simply check for empty lines.
for line in f:
if line.strip(): # strip will remove all leading and trailing whitespace such as '\n' or ' ' by default
line = line.strip("\n ' '")
line = line.split(",")
print line[1]
It can be useful to catch the exception an print the offending lines
for line in f:
line = line.strip("\n ' '")
line = line.split(",")
try:
print line[1]
except IndexError, e:
print e
print "line =", line
raise # if you don't wish to continue

Splitting uneven spaced column in Python

I tried to use the below program
import os
HOME= os.getcwd()
STORE_INFO_FILE = os.path.join(HOME,'storeInfo')
def searchStr(STORE_INFO_FILE, storeId):
with open (STORE_INFO_FILE, 'r') as storeInfoFile:
for storeLine in storeInfoFile:
## print storeLine.split(r'\s+')[0]
if storeLine.split()[0] == storeId:
print storeLine
searchStr(STORE_INFO_FILE, 'Star001')
An example line in the file:
Star001 Sunnyvale 9.00 USD Los_angeles/America sunnvaleStarb#startb.com
But it gives the below error
./searchStore.py Traceback (most recent call last): File
"./searchStore.py", line 21, in
searchStr(STORE_INFO_FILE, 'Star001') File "./searchStore.py", line 17, in searchStr
if storeLine.split()[0] == storeId: IndexError: list index out of range
I have tried printing using split function on the command line and I was able to print it.
It looks like you have an empty or blank line in your file:
>>> 'abc def hij\n'.split()
['abc', 'def', 'hij']
>>> ' \n'.split() # a blank line containing white space
[]
>>> '\n'.split() # an empty line
[]
The last 2 cases show that an empty list can be returned by split(). Trying to index that list raises an exception:
>>> '\n'.split()[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
You can fix the problem by checking for empty and blank lines. Try this code:
def searchStr(store_info_file, store_id):
with open (store_info_file) as f:
for line in f:
if line.strip() and (line.split()[0] == store_id):
print line
Adding line.strip() allows you to ignore empty lines and lines containing only whitespace.
Code has an issue if split method returns an empty list.
You can change code that calls split method and add error handling code.
Following can be done
storeLineWords = storeLine.split()
if len(storeLineWords) > 0 and storeLineWords[0] == storeId:

What is the difference between input methods? [duplicate]

This question already has answers here:
NameError when using input() [duplicate]
(2 answers)
Closed 9 years ago.
I've created a few test programs to show what I mean
import os
r = open('in.txt', 'r')
for line in r.readlines():
print line
Above program prints every line in 'in.txt' which is what I want with the others
for line in raw_input():
print line
I input "asdf" and it gives me (it also does not let me input multiple lines)
a
s
d
f
Lastly,
for line in str(input()):
print line
I input "asdf" and it gives me (does not let me input multiple lines)
Traceback (most recent call last):
File "C:/Python27/test.py", line 1, in <module>
for line in str(input()):
File "<string>", line 1, in <module>
NameError: name 'asdf' is not defined
Can someone please tell me what is going on?
What is the difference between these 3 input methods other than reading files and standard input?
raw_input() takes one line as input from the user and gives a string, and when you loop through with for ... in you're looping through the characters.
input() takes the input and executes it as Python code; you should rarely if ever use it.
(In Python 3, input does the same thing as Python 2's raw_input, and there is not a function like Python 2's input.)
If you want multiline input, try:
lines = []
while True:
line = raw_input()
if line == '': break
lines.append(line)
for line in lines:
# do stuff
pass
Input a blank line to signal end of input.
Pursuant to your secondary question in Doorknob of Snow's answer, here's sample code but be aware, THIS IS NOT GOOD PRACTICE. For a quick and dirty hack, it works alright.
def multiline_input(prompt):
"""Prompts the user for raw_input() until an empty string is entered,
then returns the results, joined as a string by the newline character"""
tmp = "string_goes_here" #editor's note: this just inits the variable
tmp_list = list()
while tmp:
tmp_list.append(tmp)
tmp = raw_input(prompt)
input_string = '\n'.join(tmp_list[1:])
return input_string
for line in multiline_input(">> ").splitlines():
print(line)

Categories