Very newbie programmer asking a question here. I have searched all over the forums but can't find something to solve this issue I thought there would be a simple function for. Is there a way to do this?
I am trying to reformat a text file so I can use it with the pandas function but this requires my data to be in a specific format.
Currently my data is in the following format of a txt file with over 1000 lines of data:
["01/09/21","00:28",7.1,75,3.0,3.7,3.7,292,0.0,0.0,1025.8,81.9,17.1,44,3.7,4.6,7.1,0,0,0.00,0.00,3.0,0,0.0,292,0.0,0.0]
["01/09/21","00:58",7.0,75,2.9,5.1,5.1,248,0.0,0.0,1025.9,81.9,17.0,44,5.1,3.8,7.0,0,0,0.00,0.00,1.9,0,0.0,248,0.0,0.0
]["01/09/21","01:28",6.9,74,2.6,4.1,4.1,248,0.0,0.0,1025.8,81.9,17.0,44,4.1,4.1,6.9,0,0,0.00,0.00,2.5,0,0.0,248,0.0,0.0
I need it as
["01/09/21","00:28",7.1,75,3.0,3.7,3.7,292,0.0,0.0,1025.8,81.9,17.1,44,3.7,4.6,7.1,0,0,0.00,0.00,3.0,0,0.0,292,0.0,0.0]
["01/09/21","00:58",7.0,75,2.9,5.1,5.1,248,0.0,0.0,1025.9,81.9,17.0,44,5.1,3.8,7.0,0,0,0.00,0.00,1.9,0,0.0,248,0.0,0.0]
This requires adding a [" at the start and adding a " at the end of the date before the comma, then adding another " after the comma and another " at the end of the time section. At the end of the line, I also need to add a ], at the end.
I thought something like this would work but the second bracket appears after the line break (\n) is there any way to avoid this?
infile=open(infile)
outfile=open(outfile, 'w')
def format_line(line):
elements = line.split(',') # break the comma-separated data up
for k in range(2):
elements[k] = '"' + elements[k] + '"' # put quotes around the first two elements
print(elements[k])
new_line = ','.join(elements) # put them back together
return '[' + new_line + ']' # add the brackets
for line in infile:
outfile.write(format_line(line))
outfile.close()
You are referring to a function before it is defined.
Move the definition of format_line before it is called in the for loop.
When I rearranged your code it seems to work.
New code:
outfile=open("outputfile","w")
def format_line(line):
elements = line.split(',') # break the comma-separated data up
for k in range(2):
elements[k] = '"' + elements[k] + '"' # put quotes around the first two elements
new_line = ','.join(elements) # put them back together
return '[' + new_line + ']' # add the brackets
for line in infile:
format_line(line)
Here is the part of my program which firstly reads a file, checking if the "name" which the user would give is in the file, if it is, then it would add onto the line, but if it isn't then it would start a new line.
r = open("Class%s.txt"%(group),"r")
lines = r.readlines()
r.close()
for i, line in enumerate(lines):
if name in line:
lines[i] = line.strip() + "\t" + str(score) + "\n"
break
else:
lines.append("\n" + name + "\t" + str(score))
w = open("Class%s.txt"%(group),"w")
w.writelines(lines)
w.close()
The problem I have with this program is that if a user named "Alexander" uses the program before a user named "Alex" does so, the program would write "Alex"'s score on the same line as "Alexander"'s as it searches each line for the characters "Alex" and not if it is the EXACT match. Thanks for any help given!
I presume each line looks like
Alexander 25 31 19 16
I suggest comparing like
if name.lower() == line.split(None, 1)[0].lower():
(compare against the line's first word, and ignore capitalization).
Just change
if name in line:
with
if name in line.strip():
This way you'll look into a list of words, not a list of characters. And you'll match complete words.
The output from my print statements outputs the correct lines of data, the output file however only contains the last lines for the 3 if statements. I have tried varying the identation but this seems to only affect the code negatively.
import sys
import tokenize
file = []
f = open('Database.txt') # Opening File
for line in f:
file.append(line) # Reading in File
f.close() # Closing File
f = open('output.txt', 'w')
for line in file: # Printing out File
#print line
tokens = line.split() # splits lines along white-space (tokenise)
#print tokens
desired = '{0:<5}'.format(tokens[0])
#print desired
lined = line.split('|') # lhs is original line
if 'Not present in Line' in line:
line1 = desired + ':' + lined[1]
#print line1
if 'Not present in TV' in line:
#print line
line2 = desired + ' : ' + ' sticking ' + ' Returning ' + '\n'
#print line2
if 'Not present in Line' not in line and 'Not present in TV' not in line:
#print line
line3 = desired + ':' + lined[1]
#print line3
f.write(line1 + line2 + line3)
f.close()
You need to indent the line
f.write(line1 + line2 + line3)
to the same level as the if statements before. Currently, it's outside the for loop and is therefore executed only after that loop has ended.
Also, you may want to add a newline character after each line:
f.write(line1 + line2 + line3 + "\n")
As Jon Clements has noted correctly, you need to think about what should happen if not all three if conditions are met - in that case, lineN variables may be undefined or may still be defined with the value from the previous iteration. In fact, it's impossible for all three conditions to be met at the same time, so you'll always encounter a NameError during the very first iteration.
Only you can decide if it makes sense to set them to a default value at the start of the for loop or to do something else.
I am reading a text file and searching data line by line, based on some condition, changing some values in the line and writing it back into another file. The new file should not contain the old Line. I have tried the following, but it did not work. I think I am missing a very basic thing.
Solution: In C++ we can increment line but in Python I am not sure how to achieve this. So as of now, I am writing old line than new line. But in the new file, I want only the new line.
Example:
M0 38 A 19 40 DATA2 L=4e-08 W=3e-07 nf=1 m=1 $X=170 $Y=140 $D=8
M0 VBN A 19 40 TEMP2 L=4e-08 W=3e-07 nf=1 m=1 $X=170 $Y=140 $D=8
The code which i tried is the following:
def parsefile():
fp = open("File1", "rb+")
update_file = "File1" + "_update"
fp_latest = open(update_file, "wb+")
for line in fp:
if line.find("DATA1") == -1:
fp_latest.write(line)
if line.find("DATA1") != -1:
line = line.split()
pin_name = find_pin_order(line[1])
update_line = "DATA " + line[1] + " " + pin_name
fp_latest.write(update_line)
line = ''.join(line)
if line.find("DATA2") != -1:
line_data = line.split()
line_data[1] = "TEMP2"
line_data =' '.join(line_data)
fp_latest.write(line_data)
if line.find("DATA3") != -1:
line_data = line.split()
line_data[1] = "TEMP3"
line_data =' '.join(line_data)
fp_latest.write(line_data)
fp_latest.close()
fp.close()
The main problem with your current code is that your first if block, which checks for "DATA1" and writes the line out if it is not found runs when "DATA2" or "DATA3" is present. Since those have their own blocks, the line ends up being duplicated in two different forms.
Here's a minimal modification of your loop that should work:
for line in fp:
if line.find("DATA1") != -1:
data = line.split()
pin_name = find_pin_order(data[1])
line = "DATA " + data[1] + " " + pin_name
if line.find("DATA2") != -1:
data = line.split()
data[1] = "TEMP2"
line =' '.join(data)
if line.find("DATA3") != -1:
data = line.split()
data[1] = "TEMP3"
line =' '.join(data)
fp_latest.write(line)
This ensures that only one line is written because there's only a single write() call in the code. The special cases simply modify the line that is to be written. I'm not sure I understand the modifications you want to have done in those cases, so there may be more bugs there.
One thing that might help would be to make the second and third if statements into elif statements instead. This would ensure that only one of them would be run (though if you know your file will never have multiple DATA entries on a single line, this may not be necessary).
If you want to write a new line in a file replacing the old content that has been readed last time, you can use the file.seek() method for moving arround the file, there is an example.
with open("myFile.txt", "r+") as f:
offset = 0
lines = f.readlines()
for oldLine in lines:
... calculate the new line value ...
f.seek(offset)
f.write(newLine)
offset += len(newLine)
f.seek(offset)
if data.find('!masters') != -1:
f = open('masters.txt')
lines = f.readline()
for line in lines:
print lines
sck.send('PRIVMSG ' + chan + " " + str(lines) + '\r\n')
f.close()
masters.txt has a list of nicknames, how can I print every line from the file at once?. The code I have only prints the first nickname. Your help will be appreciate it. Thanks.
Firstly, as #l33tnerd said, f.close should be outside the for loop.
Secondly, you are only calling readline once, before the loop. That only reads the first line. The trick is that in Python, files act as iterators, so you can iterate over the file without having to call any methods on it, and that will give you one line per iteration:
if data.find('!masters') != -1:
f = open('masters.txt')
for line in f:
print line,
sck.send('PRIVMSG ' + chan + " " + line)
f.close()
Finally, you were referring to the variable lines inside the loop; I assume you meant to refer to line.
Edit: Oh and you need to indent the contents of the if statement.
You probably want something like:
if data.find('!masters') != -1:
f = open('masters.txt')
lines = f.read().splitlines()
f.close()
for line in lines:
print line
sck.send('PRIVMSG ' + chan + " " + str(line) + '\r\n')
Don't close it every iteration of the loop and print line instead of lines. Also use readlines to get all the lines.
EDIT removed my other answer - the other one in this discussion is a better alternative than what I had, so there's no reason to copy it.
Also stripped off the \n with read().splitlines()
You could try this. It doesn't read all of f into memory at once (using the file object's iterator) and it closes the file when the code leaves the with block.
if data.find('!masters') != -1:
with open('masters.txt', 'r') as f:
for line in f:
print line
sck.send('PRIVMSG ' + chan + " " + line + '\r\n')
If you're using an older version of python (pre 2.6) you'll have to have
from __future__ import with_statement
Loop through the file.
f = open("masters.txt")
lines = f.readlines()
for line in lines:
print line
Did you try
for line in open("masters", "r").readlines(): print line
?
readline()
only reads "a line", on the other hand
readlines()
reads whole lines and gives you a list of all lines.