Let's say I have this file:
abc
def
Then I do this:
with open('test.txt', 'r+') as f:
f.write("FOO\n")
# f.readlines()
As expected, the file becomes:
FOO
def
But if I uncomment the f.readlines(), it instead becomes this:
abc
def
FOO
I could not find anything in documentation to explain this strange behaviour. Why is this happening? I do the write before the readlines.
Update. I would like to clarify my question:
Why in the first example new content is added to the BEGINNING of the file and in the second example it is added to the END of the file?
Try it online!
Related
I am writing the below mentioned simple code in python, but it does not open the file(list1.txt), I am using IDLE 3.7.0. When I write the code without the first line it works! What is the problem?
def list_from_file(a="list1.txt"):
file_pointer = open("a", 'r')
data = file_pointer.readlines()
print(data)
This is because the first line def list_from_file(a="list1.txt"): defines a function, everything below and indented (your next 3 lines in this case) belongs to it.
Basically it is a bloc of code in the main program that is only executed if you call it. It you don't it will not execute.
To call a function you have to add a line like this:
def list_from_file(a="list1.txt"):
file_pointer = open(a, 'r')
data = file_pointer.readlines()
print(data)
list_from_file()
Notice how the call is on the same indentation level as the first line, this means that this line does not belong to the function itself and thus will be executed.
Also your function have an optional argument a="list1.txt" Meaning that you can call your function with another file if you want it by calling it that way: list_from_file(a="another_list.txt"), doing so will ignore the default value you put in the function and use the one you gave during the call.
I can also notice something strange, you are storing the file you want to open inside the variable a (see your first line), but on the second line you are opening a file which name is "a", you are not opening the good file, if you want to open the file "list1.txt" you need to change the second line to:
file_pointer = open(a, 'r') # I removed the quotes around the a to use the variable with the filename
def list_from_file(a="list1.txt"):
file_pointer = open(a, 'r')
data = file_pointer.readlines()
print(data)
Remove double quotes or else it takes as string value as a not file name
I'm in the Python shell and I'm trying to understand the basics. Here is what I have typed:
doc = open('test.txt', 'w') # this opens the file or creates it if it doesn't exist
doc.write('blah blah')
doc.truncate()
I understand the first line. However, in the second line, isn't it supposed to write 'blah blah' to the file? It doesn't do that. However, when I run a truncate function to the file, 'blah blah' suddenly shows up. Can someone explain to me how this logic works?
I thought truncate was supposed to erase the contents of the file? Why does it make the previous write line show up?
From the manual:
file.truncate([size])
[...] The size defaults to the current position [...]
so as you have opened and written to the file, the current position is the end of the file. Basically, you are truncating from the end of the file. Hence the absence of effect other than actually flushing the buffers, and getting the text written to disk. (truncate flushes before truncating)
Try with truncate(0); that will empty the file.
Same as you with the context manager instead:
with open('test.txt', 'w') as doc:
doc.write('blah blah')
# doc.truncate()
The above will truncate to the current position, which is at the end of the file, meaning it doesn't truncate anything.
Do this instead, it will truncate the file at the 0th byte, effectively clearing it.
doc.truncate(0)
I see from your comments that you may still be having trouble, trouble that may be solved by using the context manager:
>>> def foofile():
... with open('/temp/foodeleteme', 'w') as foo:
... foo.write('blah blah blah')
... foo.truncate(0)
... with open('/temp/foodeleteme') as foo:
... print foo.read()
...
>>> foofile()
prints nothing.
If you don't specify size parameter. The function take current position.
If you want to erase content of file:
doc = open('test.txt', 'w') # this opens the file or creates it if it doesn't exist
doc.write('blah blah')
doc.truncate(0)
or better:
with open('test.txt', 'w') as doc:
doc.write('blah blah')
doc.truncate(0)
I'm new to programming pretty much in general and I am having difficulty trying to get this command to print it's output to the .txt document. My goal in the end is to be able to change the term "Sequence" out for a variable where I can integrate it into a custom easygui for multiple inputs and returns, but that's a story for later down the road. For the sake of testing and completion of the current project I will be just manually altering the term.
I've been successful in being able to get another program to send it's output to a .txt but this one is being difficult. I don't know if I have been over looking something simple, but I have been grounded for more time than I would like to have been on this.
When the it searches for the lines it prints the fields in the file I want, however when it goes to write it finds the last line of the file and then puts that in the .txt as the output. I know the issue but I haven't been able to wrap my head around how to fix it, mainly due to my lack of knowledge of the language I think.
I am using Sublime Text 2 on Windows
def main():
import os
filelist = list()
filed = open('out.txt', 'w')
searchfile = open("asdf.csv")
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
TheString = " ".join(filelist)
searchfile.close()
filed.write(TheString)
filed.close()
main()
It sounds like you want to the lines you are printing out collected in the variable "filelist", which will then be printed to the file at the .write() call. Only a difference of indentation (which is significant in Python) prevents this from happening:
def main():
import os
filelist = list()
filed = open('out.txt', 'w')
searchfile = open("asdf.csv")
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
TheString = " ".join(filelist)
searchfile.close()
filed.write(TheString)
filed.close()
main()
Having
filelist.append(lines)
at the same level of indentation as
print lines
tells Python that they are in the same block, and that the second statement also belongs to the "then" clause of the if statement.
Your problem is that you are not appending inside the loop, as a consequence you are only appending the last line, do like this:
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
BONUS: This is the "pythonic" way to do what you want:
def main():
with open('asdf.csv', 'r') as src, open('out.txt', 'w') as dest:
dest.writelines(line for line in src if 'sequence' in line)
def main():
seq = "Sequence"
record = file("out.txt", "w")
search = file("in.csv", "r")
output = list()
for line in search:
if seq in line: output.append(line)
search.close()
record.write(" ".join(output))
record.close()
The Problem - Update:
I could get the script to print out but had a hard time trying to figure out a way to put the stdout into a file instead of on a screen. the below script worked on printing results to the screen. I posted the solution right after this code, scroll to the [ solution ] at the bottom.
First post:
I'm using Python 2.7.3. I am trying to extract the last words of a text file after the colon (:) and write them into another txt file. So far I am able to print the results on the screen and it works perfectly, but when I try to write the results to a new file it gives me str has no attribute write/writeline. Here it the code snippet:
# the txt file I'm trying to extract last words from and write strings into a file
#Hello:there:buddy
#How:areyou:doing
#I:amFine:thanks
#thats:good:I:guess
x = raw_input("Enter the full path + file name + file extension you wish to use: ")
def ripple(x):
with open(x) as file:
for line in file:
for word in line.split():
if ':' in word:
try:
print word.split(':')[-1]
except (IndexError):
pass
ripple(x)
The code above works perfectly when printing to the screen. However I have spent hours reading Python's documentation and can't seem to find a way to have the results written to a file. I know how to open a file and write to it with writeline, readline, etc, but it doesn't seem to work with strings.
Any suggestions on how to achieve this?
PS: I didn't add the code that caused the write error, because I figured this would be easier to look at.
End of First Post
The Solution - Update:
Managed to get python to extract and save it into another file with the code below.
The Code:
inputFile = open ('c:/folder/Thefile.txt', 'r')
outputFile = open ('c:/folder/ExtractedFile.txt', 'w')
tempStore = outputFile
for line in inputFile:
for word in line.split():
if ':' in word:
splitting = word.split(':')[-1]
tempStore.writelines(splitting +'\n')
print splitting
inputFile.close()
outputFile.close()
Update:
checkout droogans code over mine, it was more efficient.
Try this:
with open('workfile', 'w') as f:
f.write(word.split(':')[-1] + '\n')
If you really want to use the print method, you can:
from __future__ import print_function
print("hi there", file=f)
according to Correct way to write line to file in Python. You should add the __future__ import if you are using python 2, if you are using python 3 it's already there.
I think your question is good, and when you're done, you should head over to code review and get your code looked at for other things I've noticed:
# the txt file I'm trying to extract last words from and write strings into a file
#Hello:there:buddy
#How:areyou:doing
#I:amFine:thanks
#thats:good:I:guess
First off, thanks for putting example file contents at the top of your question.
x = raw_input("Enter the full path + file name + file extension you wish to use: ")
I don't think this part is neccessary. You can just create a better parameter for ripple than x. I think file_loc is a pretty standard one.
def ripple(x):
with open(x) as file:
With open, you are able to mark the operation happening to the file. I also like to name my file object according to its job. In other words, with open(file_loc, 'r') as r: reminds me that r.foo is going to be my file that is being read from.
for line in file:
for word in line.split():
if ':' in word:
First off, your for word in line.split() statement does nothing but put the "Hello:there:buddy" string into a list: ["Hello:there:buddy"]. A better idea would be to pass split an argument, which does more or less what you're trying to do here. For example, "Hello:there:buddy".split(":") would output ['Hello', 'there', 'buddy'], making your search for colons an accomplished task.
try:
print word.split(':')[-1]
except (IndexError):
pass
Another advantage is that you won't need to check for an IndexError, since you'll have, at least, an empty string, which when split, comes back as an empty string. In other words, it'll write nothing for that line.
ripple(x)
For ripple(x), you would instead call ripple('/home/user/sometext.txt').
So, try looking over this, and explore code review. There's a guy named Winston who does really awesome work with Python and self-described newbies. I always pick up new tricks from that guy.
Here is my take on it, re-written out:
import os #for renaming the output file
def ripple(file_loc='/typical/location/while/developing.txt'):
outfile = "output.".join(os.path.basename(file_loc).split('.'))
with open(outfile, 'w') as w:
lines = open(file_loc, 'r').readlines() #everything is one giant list
w.write('\n'.join([line.split(':')[-1] for line in lines]))
ripple()
Try breaking this down, line by line, and changing things around. It's pretty condensed, but once you pick up comprehensions and using lists, it'll be more natural to read code this way.
You are trying to call .write() on a string object.
You either got your arguments mixed up (you'll need to call fileobject.write(yourdata), not yourdata.write(fileobject)) or you accidentally re-used the same variable for both your open destination file object and storing a string.
For some reason after my for loops I am not able to read the ouput text file.
For example :
for line in a:
name = (x)
f = open('name','w')
for line in b:
get = (something)
f.write(get)
for line in c:
get2 = (something2)
f.write(get2)
(the below works if the above is commented out only)
f1 = open(name, 'r')
for line in f1:
print line
If I comment out the loops, I am able to read the file and print the contents.
I am very new to coding and guessing this is something obvious that I am missing.However I can't seem to figure it out. I have used google but the more I read the more I feel I am missing something. Any advice is appreciated.
#bernie is right in his comment above. The problem is that when you do open(..., 'w'), the file is rewritten to be blank, but Python/the OS doesn't actually write out the things you write to disk until its buffer is filled up or you call close(). (This delay helps speed things up, because writing to disk is slow.) You can also call flush() to force this without closing the file.
The with statement bernie referred to would look like this:
with open('name', 'w') as f:
for line in b:
b.write(...)
for line in c:
b.write(...)
# f is closed now that we're leaving the with block
# and any writes are actually written out to the file
with open('name', 'r') as f:
for line in f:
print line
If you're using Python 2.5 rather than 2.6 or 2.7, you'll have to do from __future__ import with_statement at the top of your file.