Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

print()

4 views
Skip to first unread message

mattia

unread,
Oct 16, 2009, 5:04:08 PM10/16/09
to
Is there a way to print to an unbuffered output (like stdout)? I've seen
that something like sys.stdout.write("hello") works but it also prints
the number of characters!

Chris Rebert

unread,
Oct 16, 2009, 5:19:13 PM10/16/09
to mattia, pytho...@python.org
On Fri, Oct 16, 2009 at 2:04 PM, mattia <ger...@gmail.com> wrote:
> Is there a way to print to an unbuffered output (like stdout)?

Just follow your prints or stdout.write()s with calls to
stdout.flush() to flush the buffer.

You could alternatively use the -u option to the python interpreter to
make the standard streams operate unbuffered.

Cheers,
Chris
--
http://blog.rebertia.com

TerryP

unread,
Oct 16, 2009, 5:30:40 PM10/16/09
to

http://docs.python.org/3.1/library/functions.html#print

a suitable object passed that makes I/O behave as if unbuffered would
be handy, if you don't want to stdout.flush() after a print()

Dave Angel

unread,
Oct 16, 2009, 11:39:38 PM10/16/09
to mattia, pytho...@python.org
What the other responses (so far) didn't address is your comment about
"prints the number of characters."

You're presumably testing this in the interpreter, which prints extra
stuff. In particular, it prints the result value of any expressions
entered at the interpreter prompt. So if you type

sys.stdout.write("hello")

then after the write() method is done, the return value of the method
(5) will get printed by the interpreter.

Either put the statement in a real script, or do the following trick to
convince yourself:

dummy = sys.stdout.write("hello")

DaveA

Grant Edwards

unread,
Oct 17, 2009, 1:15:13 AM10/17/09
to
On 2009-10-17, Dave Angel <da...@ieee.org> wrote:
> mattia wrote:
>> Is there a way to print to an unbuffered output (like stdout)? I've seen
>> that something like sys.stdout.write("hello") works but it also prints
>> the number of characters!
>>
>>
> What the other responses (so far) didn't address is your comment about
> "prints the number of characters."
>
> You're presumably testing this in the interpreter, which prints extra
> stuff. In particular, it prints the result value of any expressions
> entered at the interpreter prompt. So if you type
>
> sys.stdout.write("hello")
>
> then after the write() method is done, the return value of the method
> (5) will get printed by the interpreter.

Except sys.stdout.write("hello") doesn't return 5. It returns
None.

I don't know what the OP is talking about when he says "prints
the number of characters":

$ python
Python 2.6.2 (r262:71600, Aug 25 2009, 22:35:31)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> import sys
>>> sys.stdout.write("hello\n")
hello
>>>
>>>

> Either put the statement in a real script, or do the following trick to
> convince yourself:
>
> dummy = sys.stdout.write("hello")

I don't see why the assignment is needed.

--
Grant

Message has been deleted

Gabriel Genellina

unread,
Oct 17, 2009, 1:52:54 AM10/17/09
to pytho...@python.org
En Sat, 17 Oct 2009 02:15:13 -0300, Grant Edwards
<inv...@invalid.invalid> escribiᅵ:

Presumably he's using Python 3:

Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
(Intel)] on win32


Type "help", "copyright", "credits" or "license" for more information.

p3> import sys
p3> sys.stdout.write("hello")
hello5

See http://bugs.python.org/issue6345

--
Gabriel Genellina

mattia

unread,
Oct 17, 2009, 6:30:32 AM10/17/09
to
Il Fri, 16 Oct 2009 22:40:34 -0700, Dennis Lee Bieber ha scritto:

> On Fri, 16 Oct 2009 23:39:38 -0400, Dave Angel <da...@ieee.org>
> declaimed the following in gmane.comp.python.general:


>
>
>> You're presumably testing this in the interpreter, which prints extra
>> stuff. In particular, it prints the result value of any expressions
>> entered at the interpreter prompt. So if you type
>>
>> sys.stdout.write("hello")
>>
>> then after the write() method is done, the return value of the method
>> (5) will get printed by the interpreter.
>>

> I was about to respond that way myself, but before doing so I
wanted
> to produce an example in the interpreter window... But no effect?
>
> C:\Documents and Settings\Dennis Lee Bieber>python ActivePython 2.5.2.2
> (ActiveState Software Inc.) based on Python 2.5.2 (r252:60911, Mar 27
> 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on win32


> Type "help", "copyright", "credits" or "license" for more information.

>>>> import sys
>>>> sys.stdout.write("hello")
> hello>>>
>
>
> PythonWin 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit
> (Intel)] on win32.
> Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin'
> for further copyright information.
>>>> import sys
>>>> sys.stdout.write("This is a test")
> This is a test
>>>>
>>>> print sys.stdout.write("Hello")
> HelloNone
>>>>
>>>>
>
> No count shows up... neither PythonWin or Windows command line/
shell

Indeed I'm using py3. But now everythong is fine. Everything I just
wanted to know was just to run this simple script (I've also sent the msg
'putchar(8)' to the newsgroup):

import time
import sys

val = ("|", "/", "-", "\\", "|", "/", "-", "\\")
for i in range(100+1):
print("=", end="")
# print("| ", end="")
print(val[i%len(val)], " ", sep="", end="")
print(i, "%", sep="", end="")
sys.stdout.flush()
time.sleep(0.1)
if i > 9:
print("\x08"*5, " "*5, "\x08"*5, sep="", end="")
else:
print("\x08"*4, " "*4, "\x08"*4, sep="", end="")
print(" 100%\nDownload complete!")

mattia

unread,
Oct 17, 2009, 7:01:35 AM10/17/09
to

Another question (always py3). How can I print only the first number
after the comma of a division?
e.g. print(8/3) --> 2.66666666667
I just want 2.6 (or 2.66)

Thanks, Mattia

Dave Angel

unread,
Oct 17, 2009, 7:03:04 AM10/17/09
to Grant Edwards, pytho...@python.org
Grant Edwards wrote:
> On 2009-10-17, Dave Angel <da...@ieee.org> wrote:
>
> <snip>

> Except sys.stdout.write("hello") doesn't return 5. It returns
> None.
>
> I don't know what the OP is talking about when he says "prints
> the number of characters":
>
>
You're right of course, I should have just tried it. I must have been
thinking of read(), or maybe write() in some other language. But I know
I've seen some problem like this, where the value the interpreter
printed was mixed with what the user wanted.
> <snip>

>
>> Either put the statement in a real script, or do the following trick to
>> convince yourself:
>>
>> dummy = sys.stdout.write("hello")
>>
>
> I don't see why the assignment is needed.
>
>
Only if write() had returned a value other than None, which is of course
not how it works, nor how it's documented.

Dave Angel

unread,
Oct 17, 2009, 10:02:27 AM10/17/09
to mattia, pytho...@python.org
Just as sys.stdout.write() is preferable to print() for your previous
question, understanding str.format() is important to having good control
over what your output looks like. It's certainly not the only way, but
the docs seem to say it's the preferred way in version 3.x It was
introduced in 2.6, so there are other approaches you might want if you
need to work in 2.5 or earlier.

x = 8/3
dummy0=dummy1=dummy2=42
s = "The answer is approx. {3:07.2f} after rounding".format(dummy0,
dummy1, dummy2, x)
print(s)


will print out the following:

The answer is approx. 0002.67 after rounding

A brief explanation of the format string {3:07.2f} is as follows:
3 selects argument 3 of the function, which is x
0 means to zero-fill the value after conversion
7 means 7 characters total width (this helps determine who many
zeroes are inserted)
2 means 2 digits after the decimal
f means fixed point format

You can generally leave out the parts you don't need, but this gives you
lots of control over what things should look like. There are lots of
other parts, but this is most of what you might need for controlled
printing of floats.

The only difference from what you asked is that this rounds, where you
seemed (!) to be asking for truncation of the extra columns. If you
really need to truncate, I'd recommend using str() to get a string, then
use index() to locate the decimal separator, and then slice it yourself.

DaveA

Dave Angel

unread,
Oct 17, 2009, 10:38:55 AM10/17/09
to mattia, pytho...@python.org
Seems to me you're spending too much energy defeating the things that
print() is automatically doing for you. The whole point of write() is
that it doesn't do anything but ship your string to the file/device. So
if you want control, do your own formatting.

Consider:

import time, sys, itertools

val = ("|", "/", "-", "\\", "|", "/", "-", "\\")

sys.stdout.write(" ")
pattern = "\x08"*8 + " {0}{1:02d}%"
for percentage, string in enumerate(itertools.cycle(val)):
if percentage>99 : break
paddednum = pattern.format(string, percentage)
sys.stdout.write(paddednum)
sys.stdout.flush()
time.sleep(0.1)
print("\x08\x08\x08\x08 100%\nDownload complete!")


Note the use of cycle() which effectively repeats a list indefinitely.
And enumerate, which makes an index for you automatically when you're
iterating through a list. And str.format() that builds our string,
including using 0 padding so the percentages are always two digits.


DaveA

Lie Ryan

unread,
Oct 17, 2009, 11:21:11 AM10/17/09
to
mattia wrote:
> Another question (always py3). How can I print only the first number
> after the comma of a division?
> e.g. print(8/3) --> 2.66666666667
> I just want 2.6 (or 2.66)

Are you sure you don't want that to be 2.7 or 2.67? Then you can use:
n = int(n * 10**2) / 10**2
else if 2.7 pr 2.67 is what you wanted, you could use:
n = round(n, 2)

Dave Angel

unread,
Oct 17, 2009, 5:04:25 PM10/17/09
to Lie Ryan, pytho...@python.org
Bad idea to use round() to make numbers format properly. No guarantees
that the print logic will then print the number rounded the way you
want. It could just as easily do 2.69999999999999 when you finally go
to print it.

Best to use format(), the way it was intended. Round to decimal while
converting to decimal. Otherwise surprises await in dark corners.

DaveA

Terry Reedy

unread,
Oct 17, 2009, 6:40:37 PM10/17/09
to pytho...@python.org
Gabriel Genellina wrote:

> Presumably he's using Python 3:

And apparently not IDLE

> Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
> (Intel)] on win32


> Type "help", "copyright", "credits" or "license" for more information.

> p3> import sys
> p3> sys.stdout.write("hello")
> hello5
>
> See http://bugs.python.org/issue6345

IDLE

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit
(Intel)] on win32

>>> import sys
>>> sys.stdout.write('abc')
abc

reported, for better or worse, in http://bugs.python.org/issue7163

Since interactive users do not usually use sys.stdout.write (versus
print), the mixed output is not usually a problem.

tjr

Mark Tolonen

unread,
Oct 17, 2009, 9:13:27 PM10/17/09
to pytho...@python.org

"Terry Reedy" <tjr...@udel.edu> wrote in message
news:hbdh51$g0f$1...@ger.gmane.org...

> Gabriel Genellina wrote:
>
>> Presumably he's using Python 3:
>
> And apparently not IDLE
>
>> Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
>> (Intel)] on win32
>> Type "help", "copyright", "credits" or "license" for more information.
>> p3> import sys
>> p3> sys.stdout.write("hello")
>> hello5
>>
>> See http://bugs.python.org/issue6345
>
> IDLE
>
> Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit (Intel)]
> on win32
>
> >>> import sys
> >>> sys.stdout.write('abc')
> abc
>
> reported, for better or worse, in http://bugs.python.org/issue7163
>
> Since interactive users do not usually use sys.stdout.write (versus
> print), the mixed output is not usually a problem.
>
> tjr

Apparently, Pythonwin has the same "problem":

PythonWin 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
(Intel)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for
further copyright information.
>>> import sys
>>> sys.stdout.write('hello')
hello
>>> print(sys.stdout.write('hello'))
helloNone

-Mark


mattia

unread,
Oct 18, 2009, 8:25:40 AM10/18/09
to

It's always good to learn something new, thanks!

mattia

unread,
Oct 18, 2009, 8:35:34 AM10/18/09
to

Yes, reading the doc I've come up with
s = "%(0)03.02f%(1)s done" % {"0": 100.0-100.0*(size/tot), "1": "%"}
but to it is not a good idea to use a dict here..

TerryP

unread,
Oct 18, 2009, 11:20:05 AM10/18/09
to
On Oct 18, 12:35 pm, mattia <ger...@gmail.com> wrote:
> Yes, reading the doc I've come up with
> s = "%(0)03.02f%(1)s done" % {"0": 100.0-100.0*(size/tot), "1": "%"}
> but to it is not a good idea to use a dict here..

Also look at the new str.format()

Gabriel Genellina

unread,
Oct 18, 2009, 6:04:11 PM10/18/09
to pytho...@python.org
En Sun, 18 Oct 2009 10:35:34 -0200, mattia <ger...@gmail.com> escribiᅵ:

> Il Sat, 17 Oct 2009 10:02:27 -0400, Dave Angel ha scritto:
>> mattia wrote:
>>> Il Fri, 16 Oct 2009 21:04:08 +0000, mattia ha scritto:
>>>
>>> Another question (always py3). How can I print only the first number
>>> after the comma of a division?
>>> e.g. print(8/3) --> 2.66666666667
>>> I just want 2.6 (or 2.66)
>>>

>> x = 8/3
>> dummy0=dummy1=dummy2=42
>> s = "The answer is approx. {3:07.2f} after rounding".format(dummy0,
>> dummy1, dummy2, x)
>> print(s)
>>
>> will print out the following:
>>
>> The answer is approx. 0002.67 after rounding
>

> Yes, reading the doc I've come up with
> s = "%(0)03.02f%(1)s done" % {"0": 100.0-100.0*(size/tot), "1": "%"}
> but to it is not a good idea to use a dict here..

No need for a dict, you could use instead:

s = "%03.02f%s done" % (100.0-100.0*(size/tot), "%")

or (%% is the way to embed a single %):

s = "%03.02f%% done" % (100.0-100.0*(size/tot),)

or even:

s = "%03.02f%% done" % (100.0-100.0*(size/tot))

but the new str.format() originally suggested by Dave Angel is better:

s = "{0:03.02f}% done".format(100.0-100.0*(size/tot))

(BTW, why 03.02f? The output will always have at least 4 chars, so 03
doesn't mean anything... Maybe you want {0:06.2f} (three places before the
decimal point, two after it, filled with 0's on the left)?)

--
Gabriel Genellina

mattia

unread,
Oct 18, 2009, 6:16:39 PM10/18/09
to
Il Sun, 18 Oct 2009 20:04:11 -0200, Gabriel Genellina ha scritto:

No need of 03, you are right, thanks.

Dave Angel

unread,
Oct 19, 2009, 4:10:20 AM10/19/09
to Gabriel Genellina, pytho...@python.org
Gabriel Genellina wrote:
> <snip>

>
> but the new str.format() originally suggested by Dave Angel is better:
>
> s = "{0:03.02f}% done".format(100.0-100.0*(size/tot))
>
> (BTW, why 03.02f? The output will always have at least 4 chars, so 03
> doesn't mean anything... Maybe you want {0:06.2f} (three places before
> the decimal point, two after it, filled with 0's on the left)?)
>
I deliberately gave an example where every specifier was a different
digit, so I could easily describe what each part did. It was intended
to be understood, not copied.

DaveA

Ethan Furman

unread,
Oct 19, 2009, 11:24:29 AM10/19/09
to pytho...@python.org
Dave Angel wrote:
>It was intended to be understood, not copied.

+1 QOTW

0 new messages