So, I am at exercise 16 of Zed Shaw's Python book.
I thought of trying out both append and truncate on the same file. I know, this does not make sense. But, I am new and I am trying to learn what would happen if I used both.
So, first I am opening the file in append mode and then truncating it and then writing into it.
But, the truncate is not working here and whatever I write gets appended to the file.
So, can someone kindly explain why the truncate would not work ? Even though I am opening the file in append mode first, I believe I am calling the truncate function after that and it should have worked !!!
Following is my code:
from sys import argv
script, filename = argv
print "We're going to erase %r." %filename
print "If you don't want that. hit CTRL-C (^C)."
print "If you do want that, hit RETURN."
raw_input("?")
print "Opening the file..."
target = open(filename, 'a')
print "Truncating the file. Goodbye!"
target.truncate()
print "Now I'm going to ask you for three lines."
line1 = raw_input("line 1: ")
line2 = raw_input("line 2: ")
line3 = raw_input("line 3: ")
print "I'm going to write these to the file."
target.write(line1 + "\n" + line2 + "\n" + line3)
print "And finally, we close it."
target.close()
Truncate the file’s size. If the optional size argument is present, the file is truncated to (at most) that size. The size defaults to the current position.
When you open your file with 'a' mode, the position is at the end of the file.
You can do something like this
f = open('myfile', 'a')
f.tell() # Show the position of the cursor
# As you can see, the position is at the end
f.seek(0, 0) # Put the position at the begining
f.truncate() # It works !!
f.close()
The argument 'a' opens the file for appending. You will need to use 'w' instead.
Related
Learning python now.
I have the following program.
Why doesn't the program print anything after the last line?
It looks like "target" doesn't have any value that was written.
(even if I open the actual file, there are no values
why is that?
I tried adding that line above the "target.close" thinking the the file doesn't get written on until that line. That did not work either.
so what is the purpose of "target.close"?
how is that "target.truncate()" gets effect right away. After that command, and the script pauses on an input, if I open the file, I can see all the data it had has been erased away.
from sys import argv
script, filename = argv
print (f"We are going to erase {filename}")
print ("If you don't want that, press CTRL + C")
print ("if you want that, press ENTER")
input("? ")
print("Opening the file.......")
target = open(filename,"w+")
print("Truncating the file....")
target.truncate()
print("Finished Truncating")
print("Gimme 3 lines...")
Line1 = input("Line 1: ")
Line2 = input("Line 2: ")
Line3 = input("Line 3: ")
print("Writing these lines to the file")
target.write(Line1 + "\n")
target.write(Line2 + "\n")
target.write(Line3 + "\n")
print ("Finally, we close it")
target.close
input("Do you want to read the file now?")
print(target.read())
target.close
is missing the () call parenthesis. That is why nothing is written.
Then if you want to read the file, you will need to reopen it:
print(open(filename).read())
Solution
target.close is missing a parenthesis, i.e. it should be target.close().
But looking at your intention, it seems that you want to do target.flush() because you are also attempting target.read() soon after - you'll be unable to read from the file if you closed it.
Why does it happen
By default a certain amount of data that is written to the file is actually stored into a buffer - in memory - before it is actually written to the file. If you want to update the file immediately, you'll need to call the flush method, i.e. target.flush() Calling target.close() will automatically flush the data that has been buffered, hence why target.close() also updates the file similar to target.flush().
I'm learning Python as a first language, my study book says to add code that reads the newly written file, however whenever I try a print target.read() the script runs but when it is supposed to output on the 4th line from last, it outputs strange unreadable characters.
from sys import argv
script, filename = argv
print "We're going to erase %r." % filename
print "If you wish to cancel, press CTRL-C."
print "To continue, press RETURN."
raw_input(">")
print "Opening the file..."
target = open(filename, 'w+')
print "Truncating the file. Bye!"
target.truncate()
print "Now I'm going to ask you for three lines."
line1 = raw_input("Line 1: ")
line2 = raw_input("Line 2: ")
line3 = raw_input("Line 3: ")
print "These will be wrote to the file."
target.write(line1)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")
print "The text in this file reads as: \n "
print target.read()
print "And finally, we close it."
target.close
read() starts reading from the current position in the file. After all the write() calls, the current position is after the last byte that was written. You need to go back to the beginning of the file to read what you just wrote:
target.seek(0)
print "The texxt in this file reads as: \n"
print target.read()
BTW, you don't need to use target.truncate(). When you open a file in w or w+ mode, it's automatically truncated.
And target.close doesn't do anything. You need parentheses to call the function, so it should be target.close(). But it would be better style to use with so the file is closed automatically.
Close the file & open it for reading before, uh, reading from it.
Change print target.read()`with
with open("example_txt.txt") as xx:
print xx.read()
target.close ---> target.close()
A few things:
As stated earlier, the w+ already starts at the beginning of the file, so your truncate() is unnecessary. Also, you aren't reading the whole file object when you do the read() since the target is on the last line which is just an /n character. If you open the txt file after, you will see your three lines and an empty line at the end from your last /n you wrote.
Typically I would think it's better practice to either build your file you want to write in memory and write the entire thing so you can check it before writing. Otherwise write incrementally, close it and re-open it for reading.
Lastly you should use the following syntax for opening files so they automatically close:
from sys import argv
script, filename = argv
print "We're going to erase %r." % filename
print "If you wish to cancel, press CTRL-C."
print "To continue, press RETURN."
raw_input(">")
print "Now I'm going to ask you for three lines."
line1 = raw_input("Line 1: ")
line2 = raw_input("Line 2: ")
line3 = raw_input("Line 3: ")
print "Opening the file..."
with open(filename, 'w+') as f:
print "These will be written to the file."
f.write(line1 + '\n')
f.write(line2 + '\n')
f.write(line3 + '\n')
print "The file will close automatically after this line."
print "The text in this file reads as: \n "
with open(filename, 'r') as f:
print f.read()
There are many other ways to do this even simpler, but this is a good alternative. If you follow along, you'll see we build our text for input, then we write each line while the file is open and it automatically closes after it leaves the 'with' block. Then we can open it safely read-only for printing the contents. We could have also appended your lines together into a single variable, printed it before writing anything to make sure it's right, and then write the entire object as one piece.
from sys import argv
script, filename = argv
print "We're going to erase %r." % filename
print "If you wish to cancel, press CTRL-C."
print "To continue, press RETURN."
raw_input(">")
print "Now I'm going to ask you for three lines."
line1 = raw_input("Line 1: ")
line2 = raw_input("Line 2: ")
line3 = raw_input("Line 3: ")
contents = line1 + '\n' + line2 + '\n' + line3 + '\n'
print "These will be written to the file.\n"
print contents
print "Opening the file..."
with open(filename, 'w+') as f:
f.write(contents)
print "The file will close automatically after this line."
I am currently on Excercise 16 in Learn Python the Hard Way and i'm having a problem with my code where it will write onto the file, but my final print command does not print the contents of the file onto the console. On my command line, it just comes up with a couple of lines of blank space.From my understand "r+"opens it in read and write mode, but the computer cannot to read it.
Could someone tell me whats wrong with it please? Any help would be appreciated :)
from sys import argv
script, file = argv
print "The name of the file is %s" % file
filename = open(file,"r+")
print "First we must write something in it "
print "Do you want to continue?Press CTRL-C if not."
raw_input()
print "Type the first line of the text"
line1 = raw_input(">")+"\n"
print "Type the second line of text"
line2 = raw_input(">")+"\n"
print "Type the third line of text"
line3 = raw_input(">")+"\n"
sum_line = line1 + line2 + line3
print "Now I will write it to the file"
filename.write(sum_line)
print "The file now says:"
#This line here does not print the contents of the file
print filename.read()
filename.close()
As included in the first answer, after writing the offset will be pointing to the end of the file. However, you don't need to close the file and reopen it. Rather do this before reading it :
filename.seek(0)
That will reset the offset at the start of the file.
Then simply read it.
filename.read()
Since you wrote into the file, the offset after writing will point to the end of the file. At that point, if you want to read the file from the beginning you'll have to close it and re-open it.
By the way, since Python 2.5 the with statement is supported and recommended to use, for example:
with open('yourfile', 'r') as f:
for line in f:
...
Using with will take care of closing the file for you!
Without having to close then reopen the file you can add filename.seek(0) which will take it back to the top of the file.
filename = open('text.txt',"r+")
print(filename.read())
lin = input()
filename.write(lin)
filename.seek(0) # take it back to top, 0 can be changed to whatever line you want
print(filename.read())
filename.close()
I am doing Learn Python the Hard Way and am on exercise 16. The study drill says to write a script using read and argv.
My code is as follows:
from sys import argv
script, file_name, pet_name = argv
print "Ah, your pet's name is %r." %pet_name
print "This will write your pet's name in a text file."
print "First, this will delete the file. "
print "Proceeding..."
writefile = open(file_name, 'w')
writefile.truncate()
writefile.write(pet_name)
writefile.close
raw_input("Now it will read. Press ENTER to continue.")
readfile = open(file_name, "r")
print readfile.read()
The code works until the end. When it says to print the file, the command line gives a blank line.
PS C:\Users\[redacted]\lpthw> python ex16study.py pet.txt jumpy
Ah, your pet's name is 'jumpy'.
This will write your pet's name in a text file.
First, this will delete the file.
Proceeding...
Now it will read. Press ENTER to continue.
PS C:\Users\[redacted]\lpthw>
I am not sure why the script is just printing a blank file.
You never called the writefile.close() method:
writefile.write(pet_name)
writefile.close
# ^^
Without closing the file, the memory buffer to help speed writing never gets flushed and the file effectively remains empty.
Either call the method:
writefile.write(pet_name)
writefile.close()
or use the file as a context manager (with the with statement) to have Python close it for you:
with open(file_name, 'w') as writefile:
writefile.write(pet_name)
Note that the writefile.truncate() call is entirely redundant. Opening a file in write mode ('w') always truncates the file already.
I am currently reading "Learn Python the hard way" and have reached chapter 16. I can't seem to print the contents of the file after writing to it. It simply prints nothing.
from sys import argv
script, filename = argv print "We are going to erase the contents of %s" % filename print "If you don\'t want that to happen press Ctrl-C"
print "If you want to continue press enter"
raw_input("?") print "Opening the file..." target = open(filename, "w")
print "Truncating the file..." target.truncate()
print "Now i am going to ask you for 3 lines"
line_1 = raw_input("Line 1: ")
line_2 = raw_input("Line 2: ")
line_3 = raw_input("Line 3: ")
final_write = line_1 + "\n" + line_2 + "\n" + line_3
print "Now I am going to write the lines to %s" % filename
target.write(final_write)
target.close
print "This is what %s look like now" %filename
txt = open(filename)
x = txt.read() # problem happens here
print x
print "Now closing file"
txt.close
You're not calling functions target.close and txt.close, instead you're simply getting their pointers. Since they are functions (or methods, to be more accurate) you need () after the function's name to call it: file.close().
That's the problem; you open the file in write mode which deletes all the content of the file. You write in the file but you never close it, so the changes are never committed and the file stays empty. Next you open it in read mode and simply read the empty file.
To commit the changes manually, use file.flush(). Or simply close the file and it will be flushed automatically.
Also, calling target.truncate() is useless, since it's already done automatically when opening in write mode, as mentioned in the comments.
Edit: Also mentioned in the comments, using with statement is quite powerful and you should use it instead. You can read more of with from http://www.python.org/dev/peps/pep-0343/, but basically when used with files, it opens the file and automatically closes it once you unindent. This way you don't have to worry about closing the file, and it looks much better when you can clearly see where the file is being used, thanks to the indentation.
Quick example:
f = open("test.txt", "r")
s = f.read()
f.close()
Can be done shorter and better looking by using with statement:
with open("test.txt", "r") as f:
s = f.read()