Modify specific index of any line in a text file [duplicate] - python

This question already has answers here:
Change specific value in CSV file via Python
(4 answers)
Closed 2 years ago.
I have this txt file with usernames and some data related to them
vac3,Javier Jerez,34,Femenino,0,0
jotaaa23,Ssef Sef,34,Masculino,0,0
asd,Asdas Asd,23,Masculino,0,0
attd,Asd Asd,23,Femenino,0,0
ssdfd,Dgs Sef ,24,Femenino,0,0
asdfsdfd,Javier Jerez,12,Masculino,0,0
I want to modify the last 2 numbers
For example vac3 won a game with 90 points in 7 shots, i want the new list to be
vac3,Javier Jerez,34,Femenino,90,7
jotaaa23,Ssef Sef,34,Masculino,0,0
asd,Asdas Asd,23,Masculino,0,0
attd,Asd Asd,23,Femenino,0,0
ssdfd,Dgs Sef ,24,Femenino,0,0
asdfsdfd,Javier Jerez,12,Masculino,0,0
I've tried everything and nothing seems to work, i know i have to read the txt to a list, then rewrite data in that list, and then overwrite the whole txt. May i get some help pls.

Try this:
with open('players.txt', 'r') as f:
players = []
data = f.readlines()
winner = 'vac3'
scores = ['90', '7']
for line in data:
player = line.split(',')
if player[0] == winner:
player[4] = scores[0]
player[5] = scores[1]
players.append(player)
with open('players.txt', 'w') as f:
f.writelines('')
for player in players:
plr = ','.join(player) + "\n"
f.write(plr)

If you don't want to use csv.reader:
who, score, shots = "vac3", 90, 7
with open("yourfile.txt", "r") as f:
with open('newfile.txt', 'w') as out:
for line in f:
fields = line.rstrip().split(',')
if fields[0] == who:
fields[4] = score
fields[5] = shots
out.write(','.join(fields) + '\n')

You can use regex to identify the pattern and replace
import re
inpt = "vac3,90,7".split(',')
fmt = f"^({inpt[0]},.*,)\d+,\d+$"
new_txt = ""
with open('t.txt', 'r') as read_f, open('new.txt', 'w') as write_f:
for line in read_f:
new_txt += re.sub(fmt, fr"\g<1>{inpt[1]},{inpt[2]}", line)
write_f.write(new_txt)

Related

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]

opencv attendance system mark student as present in csv problem

i have an attendee system made with opencv, it works but my problem is with mark student in csv file, the goal is to mark student only once a day
/////////
after reading more about csv ive found that my logic was bad.
here is the latest code to solve my problem
def markAttendance(name):
today = datetime.now().strftime("%d-%m-%Y")
if not path.exists('opencv/prezente/'+today+'.csv'):
with open('opencv/prezente/'+today+'.csv', 'w') as file:
file.write(f'{"nume"},{"timestamp"}')
with open('opencv/prezente/'+today+'.csv', 'r+') as f:
now = datetime.now().strftime("%d/%m/%Y,%H:%M")
f.write(f'\n{name},{now}')
else:
with open('opencv/prezente/'+today+'.csv', 'r+') as f:
myDataList = f.readlines()
row_count = sum(1 for row in myDataList)
exista = []
for line in myDataList:
if name not in line:
exista.append(name)
if row_count == len(exista):
now = datetime.now().strftime("%d/%m/%Y,%H:%M")
f.write(f'\n{name},{now}')
so here is my markattendance function
def markAttendance(name):
with open('opencv/attendance.csv', 'r+') as f:
myDataList = f.readlines()
for line in myDataList:
entry = line.split(',')
today = datetime.now().strftime("%d/%m/%Y")
if name in line and entry[1] == today:
print(entry[1]+" ai mai fost azi " + entry[2])
else:
now = datetime.now().strftime("%d/%m/%Y,%H:%M")
# f.write(f'\n{name},{now}')
print("ciubaca")
i have comented the line f.write because there is my problem, from my logic that part should not execute if the condition is true but instead this is what i get in console
What exactly is the problem you want to fix? My hunch is that you need an if elif statement instead of if else because right now the else statement could be triggering either if the name is not in the line or if entry[1] is not today:
def markAttendance(name):
with open('opencv/attendance.csv', 'r+') as f:
myDataList = f.readlines()
for line in myDataList:
entry = line.split(',')
today = datetime.now().strftime("%d/%m/%Y")
if name in line and entry[1] == today:
print(entry[1]+" ai mai fost azi " + entry[2])
elif name not in line and entry[1] == today:
now = datetime.now().strftime("%d/%m/%Y,%H:%M")
# f.write(f'\n{name},{now}')
print("ciubaca")
But I'd need more details on the problem to be sure.

Python3 - Nested dict to JSON

I am trying to convert multiple .txt file to "table-like" data (with columns and rows). Each .txt file should be considered as a new column.
Consider below content of the .txt file:
File1.txt
Hi there
How are you doing?
What is your name?
File2.txt
Hi
Great!
Oliver, what's yours?
I have created a simple method, that accepts the file and and integer (the file number from another method):
def txtFileToJson(text_file, column):
data = defaultdict(list)
i = int(1)
with open(text_file) as f:
data[column].append(column)
for line in f:
i = i + 1
for line in re.split(r'[\n\r]+', line):
data[column] = line
with open("output.txt", 'a+') as f:
f.write(json.dumps(data))
So above method will run two times (one time for each file, and append the data).
This is the output.txt file after I have run my script:
{"1": "What is your name?"}{"2": "Oliver, what's yours?"}
As you can see, I can only get it to create a new for each file I have, and then add the entire line.
[{
"1": [{
"1": "Hi there",
"2": "How are you doing?",
"3": "\n"
"4": "What is your name?"
},
"2": [{
"1": "Hi"
"2": "Great!",
"3": "\n",
"4": "Oliver, what's yours?"
},
}]
Update:
OK, so I played around a bit and got a bit closer:
myDict = {str(column): []}
i = int(1)
with open(text_file) as f:
for line in f:
# data[column].append(column)
match = re.split(r'[\n\r]+', line)
if match:
myDict[str(column)].append({str(i): line})
i = i + 1
with open(out_file, 'a+') as f:
f.write(json.dumps(myDict[str(column)]))
That gives me below output:
[{"1": "Hi there\n"}, {"2": "How are you doing?\n"}, {"3": "\n"}, {"4": "What is your name?"}]
[{"1": "Hi\n"}, {"2": "Great!\n"}, {"3": "\n"}, {"4": "Oliver, what's yours?"}]
But as you can see, now I have multiple JSON root elements.
Solution
Thanks to jonyfries, I did this:
data = defaultdict(list)
for path in images.values():
column = column + 1
data[str(column)] = txtFileToJson(path, column)
saveJsonFile(path, data)
And then added a new method to save the final combined list:
def saveJsonFile(text_file, data):
basename = os.path.splitext(os.path.basename(text_file))
dir_name = os.path.dirname(text_file) + "/"
text_file = dir_name + basename[0] + "1.txt"
out_file = dir_name + 'table_data.txt'
with open(out_file, 'a+') as f:
f.write(json.dumps(data))
You're creating a new dictionary within the function itself. So each time you pass a text file in it will create a new dictionary.
The easiest solution seems to be returning the dictionary created and add it to an existing dictionary.
def txtFileToJson(text_file, column):
myDict = {str(column): []}
i = int(1)
with open(text_file) as f:
for line in f:
# data[column].append(column)
match = re.split(r'[\n\r]+', line)
if match:
myDict[str(column)].append({str(i): line})
i = i + 1
with open(out_file, 'a+') as f:
f.write(json.dumps(myDict[str(column)]))
return myDict
data = defaultdict(list)
data["1"] = txtFileToJson(text_file, column)
data["2"] = txtFileToJson(other_text_file, other_column)
def read(text_file):
data, i = {}, 0
with open(text_file) as f:
for line in f:
i = i + 1
data['row_%d'%i] = line.rstrip('\n')
return data
res = {}
for i, fname in enumerate([r'File1.txt', r'File2.txt']):
res[i] = read(fname)
with open(out_file, 'w') as f:
json.dump(res, f)
First, if I understand you are trying to get as output a dictionary of dictionaries, then let me observe that what I understand to be your desired output seems to be enclosing the whole thing within a list, Furthermore, you have unbalanced open and closed list brackets within the dictionaries, which I will ignore, as I will the enclosing list.
I think you need something like:
#!python3
import json
import re
def processTxtFile(text_file, n, data):
d = {}
with open(text_file) as f:
i = 0
for line in f:
for line in re.split(r'[\n\r]+', line):
i = i + 1
d[str(i)] = line
data[str(n)] = d
data = dict()
processTxtFile('File1.txt', 1, data)
processTxtFile('File2.txt', 2, data)
with open("output.txt", 'wt') as f:
f.write(json.dumps(data))
If you really need the nested dictionaries to be enclosed within a list, then replace
data[str(n)] = d
with:
data[str(n)] = [d]

Python: Add a new line after the first word in a sentence if the first word is all caps

I'm trying to modify a txt file. The file is a movie script in the format:
BEN We’ve discussed this before.
LUKE I can be a Jedi. I’m ready.
I'd like insert a new line after the character:
BEN
We’ve discussed this before.
LUKE
I can be a Jedi. I’m ready.
How do I do this in python? I currently have:
def modify_file(file_name):
fh=fileinput.input(file_name,inplace=True)
for line in fh:
split_line = line.split()
if(len(split_line)>0):
first_word = split_line[0]
replacement = first_word+'\n'
first_word=first_word.replace(first_word,replacement)
sys.stdout.write(first_word)
fh.close()
As suggested in one of the comments, this can be done using split and isupper. An example is provided below:
source_path = 'source_path.txt'
f = open(source_path)
lines = f.readlines()
f.close()
temp = ''
for line in lines:
words = line.split(' ')
if words[0].isupper():
temp += words[0] + '\n' + ' '.join(words[1:])
else:
temp += line
f = open(source_path, 'w')
f.write(temp)
f.close()
There are multiple problems with your code.
import fileinput
def modify_file(file_name):
fh=fileinput.input("output.txt",inplace=True)
for line in fh:
split_line = line.split()
if(len(split_line)>0):
x=split_line[0]+"\n"+" ".join(split_line[1:])+"\n"
sys.stdout.write(x)
fh.close() #==>this cannot be in the if loop.It has to be at the outer for level

looping text in file python

I have 2 files i am trying to put together one has about 300 lines and the other has mabey 85.
I want to have the file with 85 to loop until it adds a line of text onto each of the other files lines.
Here is my code i put together so far
name_file = open("names.txt", "r")
year_file = open("years.txt", "r")
for line in name_file:
print line.strip()+(year_file.readline())
Here are some examples of what the output looks like when it runs out of numbers
LLOYD1999
TOMMY2000
LEON2001
DEREK2002
WARREN2003
DARRELL2004
JEROME
FLOYD
LEO
I want it to output like this
LLOYD1999
LLOYD2000
LLOYD2001
LLOYD2002
LLOYD2003
LLOYD2004
TOMMY1999
TOMMY2000
TOMMY2001
TOMMY2002
TOMMY2003
TOMMY2004
ect...
with open('years.txt') as year:
years = [yr.strip() for yr in year]
with open('names.txt') as names:
for name in names:
name = name.strip()
for year in years:
print("%s%s" % (name, year))
# Get a list of all the years so we don't have to read the file repeatedly.
with open('years.txt', 'r') as year_file:
years = [year.strip() for year in year_file]
# Go through each entry in the names.
with open('names.txt', 'r') as name_file:
for name in name_file:
# Remove any extra whitespace (including the newline character at the
# end of the name).
name = name.strip()
# Add each year to the name to form a list.
nameandyears = [''.join((name, year)) for year in years]
# Print them out, each entry on a new line.
print '\n'.join(nameandyears)
# And add in a blank line after we're done with each name.
print
name_file = open("names.txt", "r")
for line in name_file:
year_file = open("years.txt", "r")
for year in year_file:
print line.strip()+year.strip()
year_file.close()
name_file.close()
name_file = open("names.txt", "r")
year_file = open("years.txt", "r")
for line in name_file:
year = year_file.readline().strip()
if year == '': # EOF, Reopen and re read Line
year_file = open("years.txt", "r")
year = year_file.readline().strip()
print line.strip() + year

Categories