Python 3 - IndexError: string index out of range - python

I'm currently creating a programming language in Python 3.6 and for some reason, the following code produces an IndexError: string index out of range.
When I try to execute the following code in a Windows Batch File:
#echo off
python run-file.py test.ros
pause
But I'm getting the following output:
Traceback (most recent call last):
File "run-file.py", line 16, in <module>
if not(value[1][0] == "!") and ignoreline == False:
IndexError: string index out of range
Press any key to continue . . .
The run-file.py file looks like this:
from sys import argv as args
from sys import exit as quit
import syntax
try:
args[1]
except IndexError:
print("ERROR: No ROS Code file provided in execution arguments")
print("Ensure the execution code looks something like this: python run-file.py test.ros")
with open(args[1]) as f:
ignoreline = False
content = f.readlines()
content = [x.strip() for x in content]
for value in enumerate(content):
if not(value[1][0] == "!") and ignoreline == False:
firstpart = value[1].split(".")[0]
lenoffirstpart = len(value[1].split(".")[0])
afterpart = str(value[1][lenoffirstpart + 1:])
apwithcomma = afterpart.replace(".", "', '")
preprint = str(firstpart + "(" + apwithcomma + ")")
printtext = preprint.replace("(", "('")
lastprinttext = printtext.replace(")", "')")
try:
exec(str("syntax." + lastprinttext))
except Exception as e:
template = "ERROR: An error of type {0} occured while running line {1} because {2}"
message = template.format(
type(e).__name__, str(value[0] + 1), str(e.args[0]))
print(message)
quit(1)
elif content[value[0]][0] == "!!!":
ignoreline = not(ignoreline)
quit(0)
The syntax.py file looks like this:
def print_message(contents=''):
print(contents)
The test.ros file looks like this:
! This is a single line comment
!!!
This line should be ignored
and this one as well
!!!
print_message.Hello World
The problem appears to be in line 16 of the run-file.py file:
if not(value[1][0] == "!") and ignoreline == False:
I've already tried replacing value[1][0] with (value[1])[0] and other combinations with brackets to no avail.
It seems like when I try to print the value it behaves as expected and gives me ! which is the first character of the test.ros file but for some reason, it throws an exception when it's in the if statement.
If you want any more of the source, it's on Github and you can find the exact commit containing all the files here
Update/Solution
Big thanks to Idanmel and Klaus D. for helping me resolve my issue. You can view the changes I've made here

This happens because the 2nd line in test.ros is empty.
You create content in this example to be:
['! This is a single line comment',
'',
'!!!',
'This line should be ignored',
'and this one as well',
'!!!',
'',
'print_message.Hello World']
When you try to access content[1][0], you get an IndexError because it's an empty string.
Try removing the empty lines from content by adding an if to the list comprehenssion:
content = [x.strip() for x in content if x.strip()]

Related

NameError: name 'variable' is not defined. Already declared variable but still error

I tried to extract data from a text file (cisco switch logs) and convert it to CSV so I can create a table and sort out the data & create graphs out of it. So here is my code:
import pandas as pd
import csv
import time
from datetime import datetime
import os
import glob
import sys
pathh = glob.glob("C:\\Users\\Taffy R. Mantang\\Desktop\\PR logs\\*\\")
#This part of the code opens all the text with the name ISW-1.txt inside the PR logs folder
for x in pathh:
# Detect the line number in text file to know where the row begin
phrase = "Shelf Panel CPUID Power CPU(5s) CPU(1m) CPU(5m) Peak PhyMem FreeMem Mem"
file = open("{0}".format(x) + "\\ISW-1.txt")
for number, line in enumerate(file):
if phrase in line:
sh_pro = number
break
file.close()
#Convert the text file to CSV from the row determined earlier
with open("{0}".format(x) + '\\ISW-1.txt', 'r') as rf:
r = csv.reader(rf, skipinitialspace=True, delimiter=' ')
rows = list(r)
heada = rows[sh_pro]
heada.insert(0, " ")
print(heada)
#to mark the last row
skipprocessor = sh_pro + 4
for i in range(7):
if i == 0:
print(rows[skipprocessor + i])
if i == 2:
sub_heada = rows[skipprocessor + i]
sub_heada.insert(0, " ")
sub_heada.insert(1, " ")
sub_heada.insert(2, " ")
print(rows[skipprocessor + i])
if i == 4:
sub_heada = rows[skipprocessor + i]
sub_heada.insert(0, " ")
sub_heada.insert(1, " ")
sub_heada.insert(2, " ")
print(rows[skipprocessor + i])
if i == 6:
sub_heada = rows[skipprocessor + i]
sub_heada.insert(0, " ")
sub_heada.insert(1, " ")
sub_heada.insert(2, " ")
print(rows[skipprocessor + i])
Previously it worked and it printed the output successfully. However while I was experimenting with exporting the output to an excel table, suddenly there was an error saying:
Traceback (most recent call last):
File "C:\Users\Taffy R. Mantang\PycharmProjects\pythonProject\main.py", line 26, in
heada = rows[sh_pro]
NameError: name 'sh_pro' is not defined
I traced back and undo everything but it still gives the same error.
I tried to remove an indent on line 26, it managed to print(heada). but messed up the if else code down below it and not print out the rest below.
What exactly is the problem? Help :'''((
sh_pro is not defined because you are not hitting the condition if phrase in line:, I would suggest:
for number, line in enumerate(file):
if phrase in line:
sh_pro = number
break
file.close()
#Convert the text file to CSV from the row determined earlier
with open("{0}".format(x) + '\\ISW-1.txt', 'r') as rf:
r = csv.reader(rf, skipinitialspace=True, delimiter=' ')
rows = list(r)
try:
heada = rows[sh_pro]
except NameError:
# error handling
In order to declare sh_pro, the condition if phrase in line: in your for cycle should return True. So if your condition returns False then your interpreter never meets such name as sh_pro. You can try to modify your code in a way that sh_pro is declared before you want to start working with it.
for number, line in enumerate(file):
if phrase in line:
sh_pro = number
break
file.close()

Exception Error Handling in python spits out error after specifying not to

I'm trying to stop this code from giving me an error about a file I created called beloved.txt I used the FillNotFoundError: to say not to give me the error and to print the file thats not found but instead its printing the message and the error message. How can I fix it ?
def count_words(Filenames):
with open(Filenames) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + Filename + " has " + str(word_length) + " words.")
try:
Filenames = open("beloved.txt", mode="rb")
data = Filenames.read()
return data
except FileNotFoundError as err:
print("Cant find the file name")
Filenames = ["anna.txt", "gatsby.txt", "don_quixote.txt", "beloved.txt", "mockingbird.txt"]
for Filename in Filenames:
count_words(Filename)
A few tips:
Don't capitalize variables besides class names.
Use different variable names when referring to different things. (i.e. don't use Filenames = open("beloved.txt", mode="rb") when you already have a global version of that variable, and a local version of that variable, and now you are reassigning it to mean something different again!! This behavior will lead to headaches...
The main problem with the script though is trying to open a file outside your try statement. You can just move your code to be within the try:! I also don't understand except FileNotFoundError as err: when you don't use err. You should rewrite that to except FileNotFoundError: in this case :)
def count_words(file):
try:
with open(file) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + file + " has " + str(word_length) + " words.")
with open("beloved.txt", mode="rb") as other_file:
data = other_file.read()
return data
except FileNotFoundError:
print("Cant find the file name")
filenames = ["anna.txt", "gatsby.txt", "don_quixote.txt", "beloved.txt", "mockingbird.txt"]
for filename in filenames:
count_words(filename)
I also do not understand why you have your function return data when data is read from the same file regardless of that file you input to the function?? You will get the same result returned in all cases...
The "with open(Filenames) as fill_objec:" sentence will throw you the exception.
So you at least must enclose that sentence in the try part. In your code you first get that len in words, and then you check for the specific file beloved.txt. This doubled code lets you to the duplicated mensajes. Suggestion:
def count_words(Filenames):
try:
with open(Filenames) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + Filename + " has " + str(word_length) + " words.")
except FileNotFoundError as err:
print("Cant find the file name")

Program not recognizing conditional statements in for loop

I'm trying to print "None" if the input entered by the user is not found in a text file I created. It should also print if the lines if word(s) are found in the text file.
My problem right now is that it is not doing both conditionals. If I were to remove the "line not in user_pass" it would not print anything. I just want the user to be able to know if the strings entered by the user can found in the file and will print that line or "none" if it is not found.
I commented out the ones where I tried fixing my code, but no use.
My code below:
def text_search(text):
try:
filename = "words.txt"
with open(filename) as search:
print('\nWord(s) found in file: ')
for line in search:
line = line.rstrip()
if 4 > len(line):
continue
if line.lower() in text.lower():
print("\n" + line)
# elif line not in text: # the function above will not work if this conditional commented out
# print("None")
# break
# if line not in text: # None will be printed so many times and line.lower in text.lower() conditional will not work
# print("none")
except OSError:
print("ERROR: Cannot open file.")
text_search("information")
I think you need to change for line in search: to for line in search.readlines(): I don't think you're ever reading from the file... Have you tried to just print(line) and ensure your program is reading anything at all?
#EDIT
Here is how I would approach the problem:
def text_search(text):
word_found = False
filename = "words.txt"
try:
with open(filename) as file:
file_by_line = file.readlines() # returns a list
except OSError:
print("ERROR: Cannot open file.")
print(file_by_line) # lets you know you read the data correctly
for line in file_by_line:
line = line.rstrip()
if 4 > len(line):
continue
if line.lower() in text.lower():
word_found = True
print("\n" + line)
if word_found is False:
print("Could not find that word in the file")
text_search("information")
I like this approach because
It is clear where you are reading the file and assigning it to a variable
This variable is then printed, which is useful for debugging
Less stuff is in a try: clause (I like to not hide my errors, but that's not a huge deal here because you did a good job specifying OSError however, what if an OSError occured during line = line.rstrip() for some reason...you would never know!!)
If this helped I'd appreciate if you would click that green check :)
Try this:-
def find_words_in_line(words,line):
for word in words:
if(word in line):
return True;
return False;
def text_search(text,case_insensitive=True):
words = list(map(lambda x:x.strip(),text.split()));
if(case_insensitive):
text = text.lower();
try:
filename = 'words.txt'
with open(filename) as search:
found = False;
for line in search:
line = line.strip();
if(find_words_in_line(words,line)):
print(line);
found = True;
if(not found):
print(None);
except:
print('File not found');
text_search('information');
Didn't really understand your code, so making one on my own according to your requirement.

Python Code Error 3.3.2

I have recently been practicing my skills at figuring out my own problems but this one problem is persistent. This is the problematic code:
with open('login_names.txt', 'r') as f:
login_name = [line.rstrip('\n') for line in f]
k = input("name: ")
if k in login_name :
print("No errors")
else:
print("You have an error")
else:
print('fail')
#var = login_name.index[random]
check = login_pass[login_name.index[random]]
with open('login_passw.txt', 'r') as p:
login_pass = [line.rstrip('\n') for line in p]
s = input("pass: ")
if s == check :
print("Works")
else:
print("Doesn't work")
f.close()
p.close()
Basically when I run the code it says:
Traceback (most recent call last):
File "C:/Python33/Test.py", line 29, in <module>
check = login_pass[login_name.index[random]]
TypeError: 'builtin_function_or_method' object is not subscriptable
I have tried lots of different suggestions on different questions but none of them have worked for me...
If we assume that login_pass, login_name and random are defined in the namespace that line is in, the only problem you have is that you should write
check = login_pass[login_name.index(random)]
str.index is a function that returns the first index of the argument given in str, so you use () instead of [], which you would use for lists, tuples and dictionaries.

Python: File Writing Adding Unintentional Newlines on Linux Only

I am using Python 2.7.9. I'm working on a program that is supposed to produce the following output in a .csv file per loop:
URL,number
Here's the main loop of the code I'm using:
csvlist = open(listfile,'w')
f = open(list, "r")
def hasQuality(item):
for quality in qualities:
if quality in item:
return True
return False
for line in f:
line = line.split('\n')
line = line[0]
# print line
itemname = urllib.unquote(line).decode('utf8')
# print itemhash
if hasQuality(itemname):
try:
looptime = time.time()
url = baseUrl + line
results = json.loads(urlopen(url).read())
# status = results.status_code
content = results
if 'median_price' in content:
medianstr = str(content['median_price']).replace('$','')
medianstr = medianstr.replace('.','')
median = float(medianstr)
volume = content['volume']
print url+'\n'+itemname
print 'Median: $'+medianstr
print 'Volume: '+str(volume)
if (median > minprice) and (volume > minvol):
csvlist.write(line + ',' + medianstr + '\n')
print '+ADDED TO LIST'
else:
print 'No median price given for '+itemname+'.\nGiving up on item.'
print "Finished loop in " + str(round(time.time() - looptime,3)) + " seconds."
except ValueError:
print "we blacklisted fool?? cause we skippin beats"
else:
print itemname+'is a commodity.\nGiving up on item.'
csvlist.close()
f.close()
print "Finished script in " + str(round(time.time() - runtime, 3)) + " seconds."
It should be generating a list that looks like this:
AWP%20%7C%20Asiimov%20%28Field-Tested%29,3911
M4A1-S%20%7C%20Hyper%20Beast%20%28Field-Tested%29,4202
But it's actually generating a list that looks like this:
AWP%20%7C%20Asiimov%20%28Field-Tested%29
,3911
M4A1-S%20%7C%20Hyper%20Beast%20%28Field-Tested%29
,4202
Whenever it is ran on a Windows machine, I have no issue. Whenever I run it on my EC2 instance, however, it adds that extra newline. Any ideas why? Running commands on the file like
awk 'NR%2{printf $0" ";next;}1' output.csv
do not do anything. I have transferred it to my Windows machine and it still reads the same. However, when I paste the output into Steam's chat client it concatenates it in the way that I want.
Thanks in advance!
This is where the problem occurs
code:
csvlist.write(line + ',' + medianstr + '\n')
This can be cleared is you strip the space
modified code:
csvlist.write(line.strip() + ',' + medianstr + '\n')
Problem:
The problem is due to the fact you are reading raw lines from the input file
Raw_lines contain \n to indicate there is a new line for every line which is not the last and for the last line it just ends with the given character .
for more details:
Just type print(repr(line)) before writing and see the output

Categories