[ python-Bugs-621057 ] File write examples are inadequate

SourceForge.net noreply at sourceforge.net
Sat Jul 10 23:40:50 CEST 2004


Bugs item #621057, was opened at 2002-10-09 18:39
Message generated for change (Comment added) made by mcherm
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=621057&group_id=5470

Category: Documentation
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Andrew Stagg (kandrew)
Assigned to: Fred L. Drake, Jr. (fdrake)
Summary: File write examples are inadequate

Initial Comment:
The examples provided for writing to files in 
section 7.2 of the documentation are overly simple 
showing only writing of a static string.  Reading 
through 7.1 (although not actually discussing file 
I/O) helps a little as the % operator is mentioned 
but the "...C sprintf()-style format string..." 
specifiers which are valid aren't cross referenced 
(and the 'Library Reference' is a largish search 
area).  I had to find out experimentally that %f isn't 
valid although %d is.  To date, I haven't been able 
to experimentally findout how to print a list or 
tuple.

trying:
  file.write('"%s"', str(relatedMeasurements))

results in:
  TypeError: read-only buffer, tuple

The addition of examples printing a list or tuple 
would be extremely helpful.  Similarly, examples of 
using file.write() to produce print type output 
would be very illuminating.

----------------------------------------------------------------------

>Comment By: Michael Chermside (mcherm)
Date: 2004-07-10 17:40

Message:
Logged In: YES 
user_id=99874

I took a close look at this, and considered adding text like
you describe to the tutorial. However, looking at it
carefully, I think it's probably best to leave the tutorial
as it is (and close this bug). Here's my reasoning:

(1) the write() method of files takes strings. If you need
to output some structured variable, first convert it into a
string somehow, then pass that to write(). Your complaint
(if I understand correctly) was that as a beginner you came
to this and assumed that the write() method of files might
work rather like the print statement -- with special
processing allowing one to pass in other types and have them
automatically converted. You propose including one example
in the tutorial to demonstrate the correct way of doing it.

(2) The current tutorial is simple and clear. It has just
one one-line example of how to use write() (passing it a
string). This is easy to follow, and doesn't cause anyone to
confuse converting to a string with writing to a file.
*Unnecessarily* complicating this would be unwise.

(3) So the question is whether debunking your error is
"necessary" (well, whether it's worth making that part of
the tutorial more complex. I would say no, because I think
your error is uncommon. (Not to say that it didn't have
*you* fooled for a time, just that it wouldn't fool *lots*
of first-time users.) The example demonstrates how to print
a string. The truth is that strings are all that you can
print. The section on files doesn't help much for the person
who needs to learn how to convert a more complex data
structure to a string, but then I wouldn't expect it to --
that section is supposed to be about files. The other
information is in section 7.1 *immediately preceeding* the
section on files. I figure most readers will at least be
skimming the tutorial in order, and will already know how to
convert their data structures by the time they get to
section 7.2.

kandrew, please feel free to correct me if I've missed an
important point you had to make, but barring a
misunderstanding, I propose closing this bug.
-- Michael Chermside

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2002-10-28 10:45

Message:
Logged In: YES 
user_id=80475

That's cool.
I'll leave this one for Fred.
Hopefully, 2.2.6.2 can be made easier to find.

----------------------------------------------------------------------

Comment By: Andrew Stagg (kandrew)
Date: 2002-10-28 10:40

Message:
Logged In: YES 
user_id=577467

I appear to have failed to clearly state the point of this 
bug report.  It has nothing to do with debugging a 
specific piece of code and everything to do with the 
difficulty in finding the required information for an 
experienced developer to write code to perform a 
standard task.  The changes suggested to correct this 
issue as, in fact, quite simple.


Examining tutorial section 7.2:

http://www.python.org/doc/current/tut/node9.html#SE
CTION009200000000000000000


The examples provided show only static strings.

Example 1:

>>> f.write('This is a test\n')


Example 2:

>>> f.write('0123456789abcdef')


 Including even one example with a variable of any type 
would be a large step forward and this is the primary 
point of this bug report.

I.e. consider including the following example:

Printing a variable:
>>> a = 123.456
>>> f.write( '%d' % (a))

and: Printing a tuple:
>>> b = ('This', 'is', 9876.654, 'not a string')
>>> f.write(str(b))

or printing the tuple without the brackets:
>>> for element in b
...    f.write('%s ' % str(element))

I believe this to be an essential point to be made and 
addressed because every (IMI EVERY) other example of 
generating output in the tutorial that I have seen uses 
the print() function.  If you examine the language 
reference, it is quite apparent that print() accepts 
a 'expression' which is a much more flexible construct 
then the 'string' accepted by file.write().  It's obvious 
that you are aware of the difference between the two 
functions yet you appear to be insisting that there's no 
need to provide anything more then the most trivial of 
examples when discussing the more restrictive of 
them.  This bug report was raised specifically because 
of the difficulty encountered by a non-guru in 
determining what is required to make that more 
restrictive function work.

No sir, I will not withdraw the bug report at this time as 
it has not yet been addressed and the core issue here is 
not debugging a piece of code.


----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2002-10-28 10:21

Message:
Logged In: YES 
user_id=3066

Raymond:  I asked Andrew to file this bug report after he
first sent a note to the python-docs address; I do think
there's room for improvement in the docs.  i'd hoped to get
to this before now, but still intend to do so.

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2002-10-28 08:30

Message:
Logged In: YES 
user_id=80475

When coded with the proper syntax, the example runs fine:

>>> peakPres = {'meas1': 1, 'Unknown': 0}
>>> f = open('test1', 'w')
>>> for pres in peakPres:
        f.write('%s: %s, ' % (pres, peakPres[pres]))

	
>>> f.close()
>>> open('test1').read()
'Unknown: 0, meas1: 1, '


To debug your code, please do the following:
-- don't use variable names like file, list, etc
-- use the % formatting operator instead of a comma
-- build a correctly formatting string before worrying
   about writing it to a file
-- the % operator takes a single tuple argument so the
   values must be wrapped in parentheses:
        formatstring % (val1, val2, val3)

Note, the tutorial and library reference are stand-alone 
documents and do not cross reference with each other.

Recommend that you withdraw the bug report.

----------------------------------------------------------------------

Comment By: Andrew Stagg (kandrew)
Date: 2002-10-25 15:50

Message:
Logged In: YES 
user_id=577467

The comment that the example is incomplete is well 
founded.  Therefore I attach a standalone example of 
the problem I ran into:

>>> peakPres = {'Unknown':0}
>>> peakPres['meas1'] = 0
>>> peakPres['meas1'] = peakPres['meas1']+1
>>> print peakPres
{'meas1': 1, 'Unknown': 0}
>>> for pres in peakPres.keys():
... 	print pres, peakPres[pres]
... 
meas1 1
Unknown 0
>>> file.open('test1.dat', 'w')
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
NameError: file
>>> file = open('test1.dat', 'w')
>>> for pres in peakPres.keys():
... 	file.write('%s: %s, ', pres, peakPres[pres])
... 
Traceback (innermost last):
  File "<interactive input>", line 2, in ?
TypeError: read-only buffer, tuple
>>> 

Note that the call to print works while the call to 
file.write does not.  The reason is that the print 
statement makes a call to __str__.  

Thus, and file.write() do not have the same relationship 
as C++ stream classes ostream and ofstream or C's 
printf and fprintf.  (As implied by rhettinger and the 
current contents of the tutorial.)

Hence, my request that the tutorial's examples of file 
output be expanded to the non-trival level of writing 
list and dictionary members.  Cross referenceing the 
legal format specifiers (in the language reference) from 
the tutorial examples would also be extremely helpful.


----------------------------------------------------------------------

Comment By: Andrew Stagg (kandrew)
Date: 2002-10-25 15:48

Message:
Logged In: YES 
user_id=577467

The comment that the example is incomplete is well 
founded.  Therefore I attach a standalone example of 
the problem I ran into:

>>> peakPres = {'Unknown':0}
>>> peakPres['meas1'] = 0
>>> peakPres['meas1'] = peakPres['meas1']+1
>>> print peakPres
{'meas1': 1, 'Unknown': 0}
>>> for pres in peakPres.keys():
... 	print pres, peakPres[pres]
... 
meas1 1
Unknown 0
>>> file.open('test1.dat', 'w')
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
NameError: file
>>> file = open('test1.dat', 'w')
>>> for pres in peakPres.keys():
... 	file.write('%s: %s, ', pres, peakPres[pres])
... 
Traceback (innermost last):
  File "<interactive input>", line 2, in ?
TypeError: read-only buffer, tuple
>>> 

Note that the call to print works while the call to 
file.write does not.  The reason is that the print 
statement makes a call to __str__.  

Thus, and file.write() do not have the same relationship 
as C++ stream classes ostream and ofstream or C's 
printf and fprintf.  (As implied by rhettinger and the 
current contents of the tutorial.)

Hence, my request that the tutorial's examples of file 
output be expanded to the non-trival level of writing 
list and dictionary members.  Cross referenceing the 
legal format specifiers (in the language reference) from 
the tutorial examples would also be extremely helpful.


----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2002-10-23 09:58

Message:
Logged In: YES 
user_id=80475

Here are a few thoughts:

The % formatting operator is fully documented in 2.2.6.2 
of the library reference.  I think the tutorial should be kept 
at an introductory level and the details left in the reference. 
OTOH, I agree that 2.2.6.2 is hard to find.

%f is a valid format:  '%f' % 3.14

There are several oddities in the file.write error in your 
post. First, the double quotes inside the single quotes 
(perhaps this is intentional).  Second, the comma should 
have been the % formatting operator.  Third, since 'file' is 
the name of a type, it is normally a good idea to pick 
another name like 'infil' or 'outfil'.

The post doesn't include enough information to be able to 
reproduce the error.  We need to know the value of 
relatedMeasurements and have a line showing how the file 
was opened.

To debug the example, it would help to separate the 
concerns of file writing from the string formatting.  Get the 
program to successfully format and print a string.  Only 
then, add a line to write it out to a file.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=621057&group_id=5470


More information about the Python-bugs-list mailing list