IndexError: list index out of range - PythonError - python

I'm creating a program that should create a file (.txt) based on each line of 'clouds.txt'. This is my code:
def CreateFile():
global file_name
f = open(file_name,"w+")
f.write(list_email + ":")
f.close()
def WriteInConfig():
f = open("config/config.txt","a")
f.write(list_name + "\n")
f.close()
with open("clouds.txt","r") as f:
list_lines = sum(1 for line in open('clouds.txt'))
lines = f.readline()
for line in lines:
first_line = f.readline().strip()
list_email = first_line.split('|')[1] #email
print("Email: " + list_email)
list_pass = first_line.split('|')[2] #pass
print("Pass: " + list_pass)
list_name = first_line.split('|')[3] #name
print(list_name)
global file_name
file_name = "config/." + list_name + ".txt"
with open('clouds.txt', 'r') as fin:
data = fin.read().splitlines(True)
with open('clouds.txt', 'w') as fout:
fout.writelines(data[1:])
CreateFile()
WriteInConfig()
The clouds.txt file looks like this:
>|clouds.n1c0+mega01#gmail.com|cwSHklDIybllCD1OD4M|Mega01|15|39.91|FdUkLiW0ThDeDkSlqRThMQ| |x
|clouds.n1c0+mega02#gmail.com|tNFVlux4ALC|Mega02|50|49.05|lq1cTyp13Bh9-hc6cZp1RQ|xxx|x
|clouds.n1c0+mega03#gmail.com|7fe4196A4CUT3V|Mega03|50|49.94|BzW7NOGmfhQ01cy9dAdlmg|xxx|xxx >
Everything works fine until 'Mega48'. There I get "IndexError: list index out of range"
>|clouds.n1c0+mega47#gmail.com|bd61t9zxcuC1Yx|Mega47|50|10|Xjff6C8mzEqpa3VcaalUuA|xxx|x
|clouds.n1c0+mega48#gmail.com|kBdnyB6i0PUyUb|Mega48|50|0|R6YfuGP2hvE-uds0ylbQtQ|xxx|x
|clouds.n1c0+mega49#gmail.com|OcAdgpS4tmSLTO|Mega49|50|28.65|xxx| >
I checked and there are no spaces/other characters. As you could see, after creating the file, the program deletes the line. After the error, if I'm starting the program again (and starts from 'Mega47') it doesn't show the error, and everything works as planned.
Any ideas how to fix this?

I see many mistakes in your code. First, what do you want with this list_lines = sum(1 for line in open('clouds.txt'))?
You have a problem in your for loop because you did lines = f.readline() so lines is the first line, then you do for line in lines where line will be each character of the first line and there are more character in the first line than lines in your file to read.
[edited]
you don't need to know the number of lines in the file to do a for loop. You can just do for line in f:, then you don't need to read the line again with readline it is already in the variable line

Related

In Python, print(lines) only working when code below is uncommented. Not inside conditional or after return

I have a Python script that opens text files and then saves them as newly parsed files.
The code works: print(lines) on line 69 prints the parsed contents and the names of the files are also output if writing is successful.
However, if I remove or comment all of the code below line 70, print(lines) on 69 no longer works.
import os
import re
def parse_file(file_path):
# open the file
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
# read the contents
contents = f.read()
# split the contents into lines
lines = contents.split('\n')
# remove any line that includes the string "END OF TEXT FILE"
lines = [line for line in lines if "END OF TEXT FILE" not in line]
# add the part string
lines[0] = "PART, " + lines[0]
# filters out empty lines
lines = [line for line in lines if line.strip()]
# replace asterisks with an empty string
lines = [line.replace("*", "") for line in lines]
# replace asterisks with an empty string
lines = [line.replace("•", "") for line in lines]
# replace GB with an empty string
lines = [re.sub(r'\sGB', '', line) for line in lines]
# replace "MHz" with an empty string
lines = [re.sub(r'\sMHz', '', line) for line in lines]
# replace "mm" with an empty string
lines = [re.sub(r'\smm', '', line) for line in lines]
# replace W with an empty string
lines = [re.sub(r'\sw', '', line) for line in lines]
# combine the first line and second line if the second line does not start with "VRAM" or "Lighting"
if len(lines) > 1 and not lines[1].startswith("VRAM") and not lines[1].startswith("Lighting"):
lines[0] = lines[0] + " " + lines[1]
lines.pop(1)
# replace any ":" with ","
lines = [line.replace(":", ",") for line in lines]
# Trim the last entry in the list by extracting the digits after the dollar sign using a regular expression
dollar_amount_regex = r'\$(\d+)'
last_entry = lines[-1]
dollar_amount_match = re.search(dollar_amount_regex, last_entry)
# Extract the digits and construct a new string without the dollar sign
dollar_amount_digits = dollar_amount_match.group(1)
dollar_amount = dollar_amount_digits
# Replace the original string with the dollar amount
lines[-1] = dollar_amount
# add "Price, " to the last line
lines[-1] = "Price, " + lines[-1]
# remove any extra whitespace from each line
lines = [line.strip() for line in lines]
# CHECK OUTPUT
print(lines)
# WRITING TO FILES
# extract the first line from the list of lines
file_name = lines[0].strip()
# check if the lines contain the word "VRAM"
if any("VRAM" in line for line in lines):
# add "gpu-" to the front of the file name
file_name = "GPU - " + file_name
# check if the lines contain both "RAM Type" and "Frequency"
if any("RAM Type" in line for line in lines) and any("Frequency" in line for line in lines):
# add "ram-" to the front of the file name
file_name = "RAM - " + file_name
# create a new file path by joining the directory "D:\\Dev\\PAD\\pcbs-parsed-text" with the first line as the file name and .txt extension
new_file_path = os.path.join("D:\\Dev\\PAD\\pcbs-parsed-text", file_name + ".txt")
# save the lines to this file
with open(new_file_path, 'w') as f:
for line in lines:
f.write(line + '\n')
return file_name
# search for files in the folder "D:\\Dev\\PAD\\pcbs-raw-text" with "output" in the title
raw_text_dir = "D:\\Dev\\PAD\\pcbs-raw-text"
files = [f for f in os.listdir(raw_text_dir) if "output" in f]
successes = []
errors = []
# parse each file
for file in files:
file_path = os.path.join(raw_text_dir, file)
try:
file_name = parse_file(file_path)
successes.append(file_name)
except Exception as e:
errors.append(file_name)
print(f"Error parsing file {file_name}: {e}")
# check for success and print success or error, listing each file created
if errors:
print(f"Error parsing files: {errors}")
else:
print(f"Successfully parsed and saved files: {successes}")
I expected the print(lines) call to print the contents of the variable to the console but nothing happens.
To the best of my ability I've checked that print(lines) is not inside a conditional or a returned function.
I thought that Python otherwise executes top down, so I'm not sure about this one.
Still learning so it's probably something silly! Thanks.

Writing before specific line python

i have this piece of code:
asm = open(infile)
asmw = open(outfile, "w")
shutil.copyfile(infile, outfile)
for x in range(0, 8):
xorreg.append("xor " + reg[x] + ", " + reg[x])
for line in asm:
if any(s in line for s in xorreg):
found += line.count(xorreg[x])
print line
i want to write some text lines in the file right before "line" (the one printed)
how can i do that?
Thanks
This script appends to every lien containing the string Gandalf a new string The greatest wizard of all times was:
# show what's in the file
with open("some_file.txt", 'r') as f:
print f.read()
new_content = []
with open("some_file.txt", "r") as asmr:
for line in asmr.readlines():
if "Gandalf" in line:
# we have a match,we want something but we before that...
new_content += "The greatest wizard of all times was:"
new_content += line
# write the file with the new content
with open("some_file.txt", "w") as asmw:
asmw.writelines(new_content)
# show what's in the file now
with open("some_file.txt", 'r') as f:
print f.read()

Read and write to a list of names and scores - python

I am trying to create a program that gives the user a short quiz and create a score, which I have done, then I would like to add them to a list in a .txt file. In the program I will ask them their name, so say I have a list such as this;
Bob,7
Bill,5
Jane,6
and someone takes the quiz and inputs the name Bob and gets a score 4 the list will update to;
Bob,4
Bill,5
Jane,6
or someone new takes a quiz, Sarah it will change to;
Bob,4
Bill,5
Jane,6
Sarah,7
So far I have;
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line)
else:
file.write(name +',' +str(UserScore))
I've randomised the score for now to make it easier to read, however that will be from what the user answered correctly, and I thought this code would read the file then check each name from each line and if the name they entered is the same to the name in the list the line will be replaced with the name and score. However, the file just ends up blank, what am I doing wrong?
Here is what I think is a better idea using the Python pickle module:
In [1]: import pickle
In [2]: scores={'Bob':75, 'Angie':60, 'Anita':80} #create a dict called scores
In [3]: pickle.dump(scores,open('scores.dat','wb')) #dump the pickled object into the file
In [4]: !ls scores.dat #verify that the file has been created
scores.dat
In [5]: !cat scores.dat #list out the file
(dp0
S'Bob'
p1
I75
sS'Angie'
p2
I60
sS'Anita'
p3
I80
s.
In [9]: tscores = pickle.load(open('scores.dat','rb')) #Verification: load the pickled object from the file into a new dict
In [10]: tscores #Verification: list out the new dict
Out[10]: {'Angie': 60, 'Anita': 80, 'Bob': 75}
In [11]: scores == tscores #Verify that the dict object is equivalent to the newly created dict object
Out[11]: True
I tried your code and the first time you run it, then you rewrite the file in one single line. So the next time you run the script on this single line file, you get an unpack exception in the split function and hence you write nothing to the file, resulting in an empty file.
A solution could be to add the newline char again when writing the lines to the file.
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line + '\n')
else:
file.write(name +',' +str(UserScore) + '\n')
This should do what you want
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
flag = True
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line + '\n')
else:
file.write(name +',' +str(UserScore) + '\n')
flag = False
if flag:
file.write(student +',' +str(UserScore) + '\n')
I adjusted a bit of your code and took the liberty to remove the random part and name, score part. But I got some working code. I assume you can make it work for your situation.
file = open("scores.txt", "r+")
lines = file.readlines()
file.close()
us = 15
student = input('What is your name? ')
ls = []
file = open("scores.txt", "r+")
found_student = False
for line in lines:
line = line.strip()
ls = line.split(",")
print("Parsing: " + str(ls))
if not line:
print("Empty line")
pass
elif ls[0] != student:
file.write(line + "\n")
else:
found_student = True
file.write(ls[0] + ',' + str(us) + "\n")
if not found_student:
file.write(student + ',' + str(us) + "\n" )
file.close()

Why is my code printing incorrectly to the text file?

I have this code:
with open("pool2.txt", "r") as f:
content = f.readlines()
for line in content:
line = line.strip().split(' ')
try:
line[0] = float(line[0])+24
line[0] = "%.5f" % line[0]
line = ' ' + ' '.join(line)
except:
pass
with open("pool3.txt", "w") as f:
f.writelines(content)
It should take lines that look like this:
-0.597976 -6.85293 8.10038
Into a line that has 24 added to the first number. Like so:
23.402024 -6.85293 8.10038
When I use print in the code to print the line, the line is correct, but when it prints to the text file, it prints as the original.
The original text file can be found here.
When you loop through an iterable like:
for line in content:
line = ...
line is a copy1 of the element. So if you modify it, the changes won't affect to content.
What can you do? You can iterate through indices, so you access directly to the current element:
for i in range(len(content)):
content[i] = ...
1: See #MarkRansom comment.

Match the last word and delete the entire line

Input.txt File
12626232 : Bookmarks
1321121:
126262
Here 126262: can be anything text or digit, so basically will search for last word is : (colon) and delete the entire line
Output.txt File
12626232 : Bookmarks
My Code:
def function_example():
fn = 'input.txt'
f = open(fn)
output = []
for line in f:
if not ":" in line:
output.append(line)
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()
Problem: When I match with : it remove the entire line, but I just want to check if it is exist in the end of line and if it is end of the line then only remove the entire line.
Any suggestion will be appreciated. Thanks.
I saw as following but not sure how to use it in here
a = "abc here we go:"
print a[:-1]
I believe with this you should be able to achieve what you want.
with open(fname) as f:
lines = f.readlines()
for line in lines:
if not line.strip().endswith(':'):
print line
Here fname is the variable pointing to the file location.
You were almost there with your function. You were checking if : appears anywhere in the line, when you need to check if the line ends with it:
def function_example():
fn = 'input.txt'
f = open(fn)
output = []
for line in f:
if not line.strip().endswith(":"): # This is what you were missing
output.append(line)
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()
You could have also done if not line.strip()[:-1] == ':':, but endswith() is better suited for your use case.
Here is a compact way to do what you are doing above:
def function_example(infile, outfile, limiter=':'):
''' Filters all lines in :infile: that end in :limiter:
and writes the remaining lines to :outfile: '''
with open(infile) as in, open(outfile,'w') as out:
for line in in:
if not line.strip().endswith(limiter):
out.write(line)
The with statement creates a context and automatically closes files when the block ends.
To search if the last letter is : Do following
if line.strip().endswith(':'):
...Do Something...
You can use a regular expression
import re
#Something end with ':'
regex = re.compile('.(:+)')
new_lines = []
file_name = "path_to_file"
with open(file_name) as _file:
lines = _file.readlines()
new_lines = [line for line in lines if regex.search(line.strip())]
with open(file_name, "w") as _file:
_file.writelines(new_lines)

Categories

Resources