How to make automated writer to append lines in Python - python

Here is my Code :
b = 1
a = "line"
f = open("test.txt", "rb+")
if a + " " + str(b) in f.read():
f.write(a + " " + str(b + 1) + "\n")
else:
f.write(a + " " + str(b) + "\n")
f.close()
It prints now line 1 and then line 2, but how can i make this read what is the last "line x" and print out line x + 1?
for example:
test.txt would have
line 1
line 2
line 3
line 4
and my code would append line 5 in the end.
I was thinking maybe some kind of "find last word" kind of code?
How can I do this?

If you know for certain that every line has the format "word number" then you could use:
f = open("test.txt", "rb+")
# Set l to be the last line
for l in f:
pass
# Get the number from the last word in the line
num = int(l.split()[-1]))
f.write("line %d\n"%num)
f.close()
If the format of each line can change and you also need to handle extracting numbers, re might be useful.
import re
f = open("test.txt", "rb+")
# Set l to be the last line
for l in f:
pass
# Get the numbers in the line
numstrings = re.findall('(\d+)', l)
# Handle no numbers
if len(numstrings) == 0:
num = 0
else:
num = int(numstrings[0])
f.write("line %d\n"%num)
f.close()
You can find more efficient ways of getting the last line as mentioned here What is the most efficient way to get first and last line of a text file?

Related

How to only print or get the second result

I only want to get the second result, which num prints and use it.
savee1 is a .txt file
def copycoordinates():
savee1 = filedialog.askopenfilename(initialdir="C:/USERS/" + username + "/documents/Euro Truck Simulator 2/profiles", title="Choose FIRST File", filetypes=[("sii files", "*.sii")])
savee2 = filedialog.askopenfilename(initialdir="C:/USERS/" + username + "/documents/Euro Truck Simulator 2/profiles", title="Choose SECOND File", filetypes=[("sii files", "*.sii")])
i1 = Label(frame5, text="Chosen FIRST File \n" + savee1)
i1.pack()
i2 = Label(frame5, text="Chosen SECOND File \n" + savee2)
i2.pack()
command=lambda:[save1()]
subprocess.Popen(["C:/SII_Decrypt.exe", savee1])
command=lambda:[save2()]
subprocess.Popen(["C:/SII_Decrypt.exe", savee2])
#time.sleep(1)
with open(savee1, "r+") as save1:
for num, line in enumerate(save1, 1):
if "truck_placement:" in line:
print(num)
If you mean you want the second match, you can try:
with open(savee1, "r+") as save1:
match = 0
for num, line in enumerate(save1, 1):
if 'truck_placement:' in line:
match += 1
if match == 2
print(num)
else:
continue
The num will print on the second match.
There are definitely better ways, but this is one of the most easy solution.
results = list()
with open(savee1, "r+") as save1:
for num, line in enumerate(save1, 1):
if "truck_placement:" in line:
print(num)
results.append(num)
print(results[1]) #this is the value you want
not sure what's in your text file, but usually things are separated in some way (line break, tab separated, comma separated). You should split on what ever it is that separates and then you can just index the resulting list. the following code assumes the things you want are separated by new lines:
with open(save1, "r+") as infile:
f=infile.read()
list_o_txt = f.split('\n')
print (list_o_txt[1])
if you want to make a sublist of texts that only contain a phrase 'truck_placement'
with open(save1,'r') as infile:
f=infile.read()
list_o_txt = f.split('\n') # produces a list
filtered_list = [line for line in list_o_txt if 'truck_placement' in line] #filters the list
print (filtered_list[1]) #prints the second item

Read First 10 Lines in a File; If Shorter Only Read Those Lines

I want to open a file, and read the first 10 lines of a file. If a file has less than 10 lines it should read as many lines as it has. Each line has to be numbered, wether it's text or it's whitespace. Because I have to strip each line, I can't differentiate between an empty string, and the end of a file. For example if I read a file with only three lines, it will print out lines 1 - 10, with lines 4 - 10 being empty, but I would like to have it stop after reaching that 3rd line, as that would be the end of the file. I would really appreciate any help, thank you.
def get_file_name():
fileName = input('Input File Name: ')
return fileName
def top(fileName):
try:
file = open(fileName, 'r')
line = 'text'
cnt = 1
while cnt <= 10:
if line != '':
line = file.readline()
line = line.rstrip('\n')
print(str(cnt) + '.', line)
cnt += 1
else:
line = file.readline()
line = line.rstrip('\n')
print(str(cnt) + '.', line)
cnt += 1
file.close()
except IOError:
print('FILE NOT FOUND ERROR:', fileName)
def main():
fileName = get_file_name()
top(fileName)
main()
def read_lines():
f = open("file-name.txt","r")
num = 1
for line in f:
if num > 10:
break
print("LINE NO.",num, ":",line)
num = num + 1
f.close()
Here, the loop exits at the end of the file. So if you only had 7 lines, it will exit automatically after the 7th line.
However, if you have 10 or more than 10 lines then the "num" variable takes care of that.
EDIT: I have edited the print statement to include the line count as well and started the line count with 1.
with open(filename, 'r') as f:
cnt = 1
for line in f:
if cnt <= 10:
print(str(cnt) + '.', line, end='')
cnt += 1
else:
break
This should do exactly what you need. You can always remove the if/else and then it will read exactly however many lines are in the file. Example:
with open(filename, 'r') as f:
cnt = 1
for line in f:
print(str(cnt) + '.', line, end='')
cnt += 1
You can try to load all the lines into array, count the total line and use an if statement to check if total is 10 or not, then finally use a for loop like for i in range (0,9): to print the lines.

Trying to loop through multiple text files and append line 2 to a list

I'm trying to loop through a bunch of text files and append line #2 of each file to a list. Below is my sample code. This looks like it should be pretty close, but nothing at all is getting appended to my list.
import os
directory = 'C:\\my_path\\'
i=0
list2 = []
for filename in os.listdir(directory):
with open(directory + filename) as infile:
try:
print(filename)
i=i+1
print(i)
data = infile.readlines()
for line in data:
if (line == 2):
list2.append(line)
infile.close()
except:
print(filename + ' is throwing an error')
print('DONE!!')
print(list2)
When writing:
for line in data:
if (line == 2):
list2.append(line)
infile.close()
The line variable is not the index of the line but the line itself as a string.
Also note that the second line will have an index of 1, not 2 because indexes start at 0 in Python.
You should at least change this loop to:
for index, line in enumerate(data):
if (index == 1):
list2.append(line)
infile.close()
Also, as suggested by #bruno-desthuilliers, you do not need to use the readlines() method which uses memory, instead you can directly iterate on your file like this:
#no infile.readlines() needed
for index, line in enumerate(infile):
if (index == 1):
list2.append(line)
infile.close()
Finally, you do not need to call infile.close() as you're wrapping the statement in a with block. The call is made for you.
When you test if line == 2, you are asking wether the line you read from infile is equal to 2 (which it never is). Instead, you need some counter to test if you are at line 2. Or even better, just index into it:
data = infile.readlines()
list2.append(data[1]) # the line at index 1 is the second line
line == 2 in your code tries to compare a text/string with number 2 which won't help to catch the ordinal number of the line being read.
Instead, just skip the 1st line and append the next one to the resulting list.
Note:
no need to read all lines infile.readlines() if you only need the 2nd line!
no need to close the file handler when using context manager with ...
import os
directory = 'C:\\my_path\\'
list2 = []
for filename in os.listdir(directory):
with open(directory + filename) as infile:
try:
print(filename)
next(infile)
list2.append(next(infile))
except:
print(filename + ' is throwing an error')
print('DONE!!!')
print(list2)
Try this version:
import os
directory = 'C:\\my_path\\'
secondLines = []
for filename in os.listdir(directory):
try:
#Use open() because it is optimized and does not read the whole file into RAM
with open(directory + "\\" + filename) as infile:
for lineIndex, line in enumerate(infile):
if lineIndex == 1:
secondLines.append(line)
except:
print(filename + ' is throwing an error')
print(secondLines)
Your version:
import os
directory = 'C:\\my_path\\'
i=0
list2 = []
for filename in os.listdir(directory):
#add "\\" to read the correct file
with open(directory + "\\" + filename) as infile:
try:
print(filename)
i=i+1
print(i)
data = infile.readlines()
#To get the second line, you have to use indexes
for line in range(len(data)):
#if line (index) equals 1, it is the second line (0th element is first)
if (line == 1):
#If the index of the line is 1, append it to the list
#data[line] = take the element on index 1 from list data. Indexing starts at 0
list2.append(data[line])
infile.close()
except:
print(filename + ' is throwing an error')
print('DONE!!')
print(list2)
Another elegant way of doing it is following, which takes care of not iterating through all the data as well as opening and closing the file automatically.
# With open should take care of automatic opening and closing of file. You don't need to close it explicitly.
with open(directory + filename) as infile:
try:
print(filename)
i=i+1
print(i)
skip_count = 0
line in infile:
skip_count += 1
if skip_count == 2:
list2.append(line)
break # This will go out of loop and you don't have to iterate through all the data
except:
print(filename + ' is throwing an error')

How to append strings specified in the text file to the end of every following line?

The text file is:
ar
abcd
ak
abcd
efgh
tx
abcd
I would like to end up with something like:
abcd, ar
abcd, ak
efgh, ak
abcd, tx
I have this code:
file_name1 = "file1.txt"
file_name2 = "file2.txt"
with open(file_name2, 'w') as out_file:
with open(file_name1, 'r') as in_file:
for line in in_file:
if len(line) == 3:
out_file.write(line.rstrip('\n') + line + '\n')
However, this appends the same line to any line that's length 2 (+ \n).
Loop over the lines and save the last 2-letter line you see, and update it every time you encounter a 2-letter line. For other lines, prepend it with the last line you saved.
with open('source.txt') as source, open('dest.txt', 'w') as dest:
last_two_lettered_line = None
for line in source:
line = line.strip()
if not line:
continue
if len(line) == 2:
last_two_lettered_line = line
continue
if not last_two_lettered_line:
continue
modified = '{line}, {two}'.format(line=line, two=last_two_lettered_line)
dest.write(modified + '\n')
which gives you:
abcd, ar
abcd, ak
efgh, ak
abcd, tx
The main problem in your text file is the '\n' in empty lines, then the next problem you had is that you are notice only to words in length of 3.
You can use this code to make it by the word number, if you are keeping this format, if you want to do the same but you want to make the term under word length, you may change it:
file_name1 = "file1.txt"
file_name2 = "file2.txt"
word_count = 0
with open(file_name2, 'w') as out_file:
with open(file_name1, 'r') as in_file:
for str in in_file:
if (str != '\n'):
word_count += 1
if word_count % 2 == 1:
prev = str
elif word_count % 2 == 0:
out_file.write(str.rstrip('\n') + ',' + prev)
You must clarify what the term is, to make it right. (Since if the term is that only second word will be attach before the last one, it work's)

Why does this variable an empty sequence?

The code i am using is selecting the highest number out of three in a text file set out as
R 3 5 7
F 2 9 6
I 6 3 5
When it is run it does wright the correct infomation to the text file but comes up with
max_in_line = max(nums)
ValueError: max() arg is an empty sequence
my code is
with open (classno, 'r') as f, open("class11.txt", 'w') as fout:
for line in f.readlines(): #does right swaps around
if not line.strip(): continue
parts = line.split()
nums_str = line.split()[1:]
nums = [int(n) for n in nums_str]
max_in_line = max(nums)
print (max_in_line)
print (line)
score = (max_in_line)#same problem
name = (parts[0])
fout.write(("\n") + str(score) + (" ") + (name))
fout.close
f.close#it does write them but comes up with the problem
Try this code, just skip the empty line or empty element in the list:
with open ('classno.txt', 'r') as f, open("class11.txt", 'w') as fout:
lines = [line.strip() for line in f]
for line in lines:
splitted = [i for i in line.split(' ') if i]
nums = splitted[1:]
max_nums = max(map(int, nums))
name = splitted[0]
fout.write('\n' + str(max_nums) + ' ' + name)
It works for me, hope helps.

Categories