13

I have a python script for simulation, it takes fairly long time to run through a for loop and each loop takes different time to run, so I print a . after each loop as a way to monitor how fast it runs and how far it went through the for statement as the script runs.

for something:
    do something
    print '.',

However, as I run the script in iPython in terminal, the dots does not print one by one, instead it prints them all at once when the loop finishes, which made the whole thing pointless. How can I print the dots inline as it runs?

LWZ
  • 10,440
  • 19
  • 59
  • 79
  • 5
    [Line buffering](http://stackoverflow.com/questions/107705/python-output-buffering), most likely. Try issuing a `sys.stdout.flush()` after you print. If that solves your issue, buffering is actually your problem. – Lukas Graf Sep 17 '14 at 18:02
  • 1
    You could also set stdout to unbuffered… but the usual way to do something like this is exactly what @LukasGraf suggests. Except you probably want `sys.stdout.write('.')`, not `print '.',`. First, `print` will give you spaces between the dots. Second, it's theoretically allowed to do its own buffering on top of whatever `stdout` does (although CPython doesn't, and I don't know of any implementation that does). – abarnert Sep 17 '14 at 18:07
  • Yes it worked. Thanks!! I wonder if there's a better to do it than just printing the dots though... – LWZ Sep 17 '14 at 18:07
  • `sys.stdout.write` is what I recommend as well. For a workaround (e.g. you can't modify the source code), you can try running Python with `-u` as described [here](https://docs.python.org/2/using/cmdline.html#cmdoption-u) – mtik00 Sep 17 '14 at 18:08
  • @LWZ I don't know about *better*. But you could use a `curses`-based Text UI framework like [Urwid](http://urwid.org/) and draw a fancy [progress bar](http://urwid.org/reference/widget.html?highlight=progress#progressbar). Urwid would then automatically take care of buffering / screen redrawing issues for you. But it's a *lot* more work and would add a significant dependency to your project. – Lukas Graf Sep 17 '14 at 18:10
  • 1
    Even though your question is about *why*, the obvious follow up question would be *"How do I turn off buffering then?"*, so I voted to mark it as a duplicate. – Lukas Graf Sep 17 '14 at 18:13

1 Answers1

13

How can I print the dots inline as it runs?

Try flushing your output, like so:

for _ in range(10):
    print '.',
    sys.stdout.flush()
    time.sleep(.2)  # or other time-consuming work

Or for Python 3.x:

for _ in range(10):
    print('.', end=' ', flush=True)
    time.sleep(.2)  # or other time-consuming work
Georgy
  • 9,972
  • 7
  • 57
  • 66
Robᵩ
  • 154,489
  • 17
  • 222
  • 296