Eddie Eddie - 1 month ago 18
Python Question

How can I simplify this series of target.write commands?

I'm working my way through Zed Shaw's "Learn Python The Hard Way". I'm up to exercise 16 ( http://learnpythonthehardway.org/book/ex16.html ) and am running into a problem figuring out extra credit # 3. There are a series of 6 target.write commands towards the bottom of the script and Zed wants me to simplify them into a single target.write command using strings, formats and escapes.

Here is the original script with the 6 target.write commands...

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, 'w')

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)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")

print "And finally, we close it."
target.close()


First I tried condensing the target.write commands like this...

target.write (line1, line2, line3)


When I run the script I get; TypeError: function takes exactly 1 argument (3 given)

Then I tried...

target.write "I love %r and %r and %r." % (line1, line2, line3)


I get SyntaxError: invalid syntax

I also tried...

target.write (line1), (line2), (line3)


This time the script ran to competition without any errors, but when I open the file that the script is supposed to write to (text.txt) it only wrote the first string (line1) into the file, but not the other two strings (line2) and (line3).

Finally, I tried this...

target.write (line1, "\n", line2 "\n", line3, "\n")


But again I got an SyntaxError: invalid syntax

Can someone point me in the right direction on this?

Much appreciated.

Eddie

Answer

You could do

target.write('\n'.join((line1,line2,line3))+'\n')

Or, maybe written a little more clearly:

lines=(line1,line2,line3)
target.write( '\n'.join(lines) + '\n')

Although, in this case, I might actually write the last newline separately to avoid the overhead of creating an entirely new string just to add on a newline at the end (and I think it looks cleaner):

lines=(line1, line2, line3)
target.write('\n'.join(lines))
target.write('\n')

This takes your lines, packs them together as a tuple and uses the join method of string objects to make them into a single string which gets written.

The advantage to this approach (as opposed to string formatting) is that you don't need to know a-priori how many "lines" you are going to write. Any iterable object will do work in place of the tuple in the above expression.