Python - Problem in appending lines to output file with specific condition - python

My Problem is the following:
I have a file with lines that normally start with 'ab', condition is when line not start with ab it should be appended to previous line, but some lines are not get appended to output file
Source File:
grpid;UserGroup;Name;Description;Owner;Visibility;Members -> heading
ab;user1;name1;des1;bhalji;public
sss
ddd
fff
ab;user2;name2;des2;bhalji;private -> not appended in output
ab;user3;name3;des3;bhalji;public -> not appended in output
ab;user4;name4;des4;bhalji;private
rrr
ttt
yyy
uuu
ab;user5;name5;des5;bhalji;private
ttt
ooo
ppp
Here's is what I'm doing using python:
def grouping():
output = []
temp = []
currIdLine = ""
with( open ('usergroups.csv', 'r')) as f:
for lines in f.readlines():
line = lines.strip()
if not line:
print("Skipping empty line")
continue
if line.startswith('grpid'):
output.append(line)
continue
if line.startswith('ab'):
if temp:
output.append(currIdLine + ";" + ','.join(temp))
temp.clear()
currIdLine = line
else:
temp.append(line)
output.append(currIdLine + ";" + ','.join(temp))
#print("\n".join(output))
with open('new.csv', 'w') as f1:
for row in output:
f1.write(row + '\n')
grouping ()
Output of the above code:
grpid;UserGroup;Name;Description;Owner;Visibility;Members
ab;user1;name1;des1;bhalji;public;sss,ddd,fff
ab;user4;name4;des4;bhalji;private;rrr,ttt,yyy,uuu
ab;user5;name5;des5;bhalji;private;ttt,ooo,ppp
I hope this should be quite easy with Python but I'm not getting it right so far.
That's how the file should look at the end:
Expected Output:
grpid;UserGroup;Name;Description;Owner;Visibility;Members
ab;user1;name1;des1;bhalji;public;sss,ddd,fff
ab;user2;name2;des2;bhalji;private
ab;user3;name3;des3;bhalji;public
ab;user4;name4;des4;bhalji;private;rrr,ttt,yyy,uuu
ab;user5;name5;des5;bhalji;private;ttt,ooo,ppp

You are close. Missing an else statement to deal with the case that the line starts with ab, and the previous line started with ab.
def grouping():
output = []
temp = []
currIdLine = ""
with(open('usergroups.csv', 'r')) as f:
header = f.readline()
output.append(line.strip())
temp = []
for line in f.readlines():
if not line:
print("Skipping empty line")
continue
if line.startswith('ab'):
if temp:
output.append(currIdLine + ";" + ','.join(temp))
temp = []
else:
output.append(currIdLine)
currIdLine = line.strip()
else:
temp.append(line.strip())
if temp:
output.append(currIdLine + ";" + ','.join(temp))
else: # <-- this block is needed
output.append(currIdLine)
with open('new.csv', 'w') as f1:
for row in output:
f1.write(row + '\n')

Related

problems with appending Lines to output file in python

My Problem is the following
I have one file, it contains more than 1000 rows, i am getting expected output , problem is some lines get skipped not appended to output file.i have tried but failed to found the issue
def grouping():
global date,os
try:
output = []
temp = []
currIdLine = ""
with( open ('usergroups.csv', 'r')) as f:
for lines in f.readlines():
line = lines.strip()
if not line:
continue
if line.startswith('uuid'):
output.append(line)
continue
if line.startswith('id:'):
if temp:
#print(temp)
output.append(currIdLine + ";" + ','.join(temp))
temp.clear()
currIdLine = line
else:
temp.append(line)
output.append(currIdLine + ";" + ','.join(temp))
with open('usergroup.csv', 'w') as f1:
for row in output:
f1.write(row + '\n')
print("Emails appended to Previous line")
CSV = 'usergroups.csv'
if(os.path.exists(CSV) and os.path.isfile(CSV)):
os.remove(CSV)
except:
print("Emails appended - Failed")
my sample source file:
uuid;UserGroup;Name;Description;Owner;Visibility;Members ----> header
id:;group1;raji;xyzabc;ramya;public;
abc
def
geh
id:;group2;ram;xyzabc;mitu;public; ---> This line not appended to output file
id:;group3;ram;xyzabc;mitu;public; ---> This line not appended to output file
id:;group4;raji;rtyui;ramya;private
cvb
nmh
poi
output of the above code
uuid;UserGroup;Name;Description;Owner;Visibility;Members ----> header of the file
id:;group1;raji;xyzabc;ramya;public;abcdefgeh
id:;group4;raji;rtyui;ramya;private
my desired output:
uuid;UserGroup;Name;Description;Owner;Visibility;Members ----> header of the file
id:;group1;raji;xyzabc;ramya;public;abcdefgeh
id:;group2;ram;xyzabc;mitu;public;
id:;group3;ram;xyzabc;mitu;public;
id:;group4;raji;rtyui;ramya;private
finally found the mistake. mentioned my mistake here
if temp:
#print(temp)
output.append(currIdLine + ";" + ','.join(temp))
temp.clear()
**else: # <-- this block is needed**
output.append(currIdLine)

Code that concatenates new lines does not execute else statement

with open('small_plate_data.txt', 'r') as f:
for line in f.read().split("\n"):
p = 1
op = ''
cntr = 2
num_plate = 0
if line.startswith("Plate"):
with open('Plate' + str(cntr) + '.txt', 'w+') as opf:
opf.write("Plate"+ str(num_plate) + "Data")
opf.write(op)
opf.close
op = ''
cntr += 1
p += 1
num_plate +=1
else:
op = op + '\n' + line
f.close()
The code above opens a txt file and reads it line by line. It concatenates every line together unless a line begins with 'plate', where it then takes whatever has been concatenated and then saves it to a file. The problem is that it doesn't concatenate...and never executes the else statement.

Lines missing in python

I am writing a code in python where I am removing all the text after a specific word but in output lines are missing. I have a text file in unicode which have 3 lines:
my name is test1
my name is
my name is test 2
What I want is to remove text after word "test" so I could get the output as below
my name is test
my name is
my name is test
I have written a code but it does the task but also removes the second line "my name is"
My code is below
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
with open(r"test.txt", "w") as fp:
fp.write(txt)
It looks like if there is no keyword found the index become -1.
So you are avoiding the lines w/o keyword.
I would modify your if by adding the condition as follows:
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
elif index < 0:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
No need to add \n because the line already contains it.
Your code does not append the line if the splitStr is not defined.
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index != -1:
txt += line[:index + len(splitStr)] + "\n"
else:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
In my solution I simulate the input file via io.StringIO. Compared to your code my solution remove the else branch and only use one += operater. Also splitStr is set only one time and not on each iteration. This makes the code more clear and reduces possible errore sources.
import io
# simulates a file for this example
the_file = io.StringIO("""my name is test1
my name is
my name is test 2""")
txt = ""
splitStr = "test"
with the_file as fp:
# each line
for line in fp.readlines():
# cut somoething?
if splitStr in line:
# find index
index = line.find(splitStr)
# cut after 'splitStr' and add newline
line = line[:index + len(splitStr)] + "\n"
# append line to output
txt += line
print(txt)
When handling with files in Python 3 it is recommended to use pathlib for that like this.
import pathlib
file_path = pathlib.Path("test.txt")
# read from wile
with file_path.open('r') as fp:
# do something
# write back to the file
with file_path.open('w') as fp:
# do something
Suggestion:
for line in fp.readlines():
i = line.find('test')
if i != -1:
line = line[:i]

How can I get the line of index + 1 when enumerating lines in Python

I am reading through the lines of a file using the code for index, line in enumerate(lines):. I can access the string of the current line using (line).
Is it possible to access the next line to look ahead? I have tried to access this by using next_line = line(index + 1) but this is creating an error.
Code
with open(sys.argv[1]) as f1:
with open(sys.argv[2], 'a') as f2:
lines = f1.readlines()
prev_line = ""
string_length = 60
for index, line in enumerate(lines):
next_line = line(index + 1)
print(f'Index is {index + 1}')
# Do something here
line is a string therefore you can not do what you need.
Try something like this:
with open(sys.argv[1]) as f1:
with open(sys.argv[2], 'a') as f2:
lines = f1.readlines()
prev_line = ""
string_length = 60
for index, line in enumerate(lines):
try:
next_line = lines[index + 1]
except IndexError:
pass
print(f'Index is {index + 1}')
# Do something here
You can just access it from the list as you normally would, this will cause an exception on the last iteration so I added a check to prevent this:
with open(sys.argv[1]) as f1:
with open(sys.argv[2], 'a') as f2:
lines = f1.readlines()
prev_line = ""
string_length = 60
for index, line in enumerate(lines):
if index < len(lines) - 1:
next_line = lines[index+1]
print(f'Index is {index + 1}')
# Do something here

Reading and Printing multiple files into one outfile

When reading and printing through my files, printing through my cousole gives me the correct result, but writing to the outfile does not
with infile as f :
lines = f.readlines()
new_line = " "
for line in lines:
new_line = ''.join(line).replace('*',letter.upper())
new_line = new_line.replace(':',letter.lower())
print(new_line)
This prints out all of the letters that I inputted
with infile as f :
lines = f.readlines()
new_line = " "
for line in lines:
new_line = ''.join(line).replace('*',letter.upper())
new_line = new_line.replace(':',letter.lower())
outfile.write(new_line)
It only gives me the last letter of the word inputted.
folder = r"C:\Users\sarah\Documents\a CPS 111\Bonus PA\stars\stars"
# os.listdir(folder) returns a list of files in folder
file_list = os.listdir(folder)
letter_art = {}
word = str(input("Please input a letter: "))
word = word.upper()
for fname in file_list:
letter_extension_list = fname.split(".")
for letter in word:
key = letter
value = letter_extension_list[1]
value = "%s."%(key) + value
letter_art[key] = value
fname = "\\".join([folder, value])
infile = open(fname, "r")
outfile = open("word_art.txt", "w")
with infile as f :
lines = f.readlines()
new_line = " "
for line in lines:
new_line = ''.join(line).replace('*',letter.upper())
new_line = new_line.replace(':',letter.lower())
print(new_line)
outfile.write(new_line)
infile.close()
outfile.close()
This is the code I am currently working with. I am taking in symbols from a txt file and changing them to the coornading letter depending on what the user inputed
Open the output file before the loop instead of within it:
outfile = open("word_art.txt", "w")
for letter in word:
with open("test.txt",'r') as f :
lines = f.readlines()
with open('out.txt','w') as outfile:
for line in lines:
new_line = line.replace('*',letter.upper())
new_line = new_line.replace(':',letter.lower())
outfile.write(new_line)
This worked for me.
EDIT:
TigerhawkT3 is correct. I checked out your full code and you were opening the file again and again inside the loop, each time discarding the prior changes.

Categories