[Tutor] editTextFile.py

Luke Paireepinart rabidpoobear at gmail.com
Thu Sep 13 05:59:03 CEST 2007


Christopher Spears wrote:
> I created a script that opens an existing text file,
> allows the user to write over the original contents,
> and then save the file.  The original contents are
> then saved in a separate file.  Here is the script:
>
> #!/usr/bin/python
>
> 'editTextFile.py -- write over contents of existing
> text file'
>
> import os, string
>
> # get filename
> while True:
>     fname = raw_input('Enter file name: ')
>     if not (os.path.exists(fname)):
>         print"*** ERROR: '%s' doesn't exist" % fname
>     else:
>         break
>
> # get file content (text) lines
> all = []
> print "\nEnter lines ('.' by itself to quit).\n"
>
> # loop until user terminates input
> while True:
>     entry = raw_input('> ')
>     if entry == '.':
>         break
>     else:
>         all.append(entry)
>
> # write lines to file with NEWLINE line terminator
> print "1) Replace file's contents"
> print "Any other key quits function without replacing
> file's contents"
> choice = raw_input("Make a choice: ")
>
> if choice == '1':
>     fobj = open(fname, 'r')
>     fobj_lines = fobj.readlines()
>     fobj.close()
>     fobj = open(fname, 'w')
>     
>     fname_orig = fname + '_orig'
>     fobj_orig = open(fname_orig, 'w')
>     stripped_lines = []
>     for line in fobj_lines:
>     	string.strip(line)
> 	stripped_lines.append(line)
>     fobj_orig.write('\n'.join(stripped_lines))
>     fobj_orig.close()
>     
>     fobj.write('\n'.join(all))
>     fobj.close()
>     print 'DONE!'
> else:
>     print 'Bye!'
>
> I took a file called myfile.  The original contents of
> myfile were:
> Hi!
> This is my file.
> It really rocks!
>
> I then ran my script:
> Enter file name: myfile
>
> Enter lines ('.' by itself to quit).
>
>   
>> test
>> test
>> test
>> .
>>     
> 1) Replace file's contents
> Any other key quits function without replacing file's
> contents
> Make a choice: 1
> DONE!
>
> Now the contents of myfile are:
> test
> test
> test
>
> The original contents were saved in myfile_orig.  The
> contents of myfile_orig are:
> Hi!
>
> This is my file.
>
> It really rocks!
>
> Extra newlines were added.  This won't do.  I think
> the problem lies with 
>
> fobj_orig.write('\n'.join(stripped_lines))
>
> However, when I rewrite this line code as
>
> fobj_orig.write(string.join(stripped_lines))
>
> I get 
>
> Hi!
>  This is my file.
>  It really rocks!
>
> That doesn't work either.  Any suggestions?
>   
Before you write to the file, just use one of the os module functions to 
rename the original file to the new filename.  Then when you go to open 
the original file, it'll just create a new one.
The way you're currently doing it now, there's a period where both 
file's data is stored in memory, after you've opened both files for 
writing.  This means that if the program were to crash at some point in 
here,  you'll lose your original data.  This is a pretty big problem for 
a text editor :)

As per your original question, we can use reasoning to figure out what 
the problem is.
There are extra spaces on every line except the first.
However, there are still newlines.
This means that your original strings must have had newlines.
The spaces are explained by the string.join method.
(Methods of string are deprecated anyway.)
We can deduce that by default string.join uses space as the separation 
character.
But by leiu of the example "\n".join() we know we can say 
"somestring".join(strings_to_join) and it will join the strings with 
that character in between each string.
" ".join(stripped_lines) would have the same effect as 
string.join(stripped_lines).  So what do you do if you don't want any 
characters at all separating your strings?  Simple: use an empty string:
"".join(stripped_lines)

As I mentioned above, there are multiple ways to approach this problem.  
One other thing you could do if you wanted the program to be 
functionally equivalent is just use writelines() instead of write() and 
then you don't have to join the strings.
-Luke


More information about the Tutor mailing list