4
import os
import time

h = 0
s = 0
m = 0

while s <= 60:
    os.system('clear')
    print h, "hours", m, 'minutes', s, 'seconds'
    time.sleep(1)
    s += 1
    if s == 60:
        m += 1
        s = 0
    elif m == 60:
        h += 1
        m = 0
        s = 0

I have this code above. It all works fine and does what it is meant to do, but I want to make it so that it prints all the statements in the same line. For example, it should print out 0 hours 0 minutes 0 seconds and then on the same line should print out 0 hours 0 minutes 1 second, with the second variable the only thing that is changing. How do I do this? I have already tried using the os.system('clear') command but it does not work. Im running this on Mac OSX 10.7.

Nirvik Baruah
  • 1,643
  • 2
  • 19
  • 20
  • 1
    http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space – jab Feb 05 '14 at 10:36

3 Answers3

3

You should use what your terminal provides. In most cases you need to use '\r' (carriage return, return to first column in that line); but depending on the operating system this might be interpreted such that it also appends a line feed. I feel I remember that OSX might do this.

Also you need to avoid the automatic newline print will always append. You could use a trailing comma for this, but this has issues (stray space, no flushing). So I propose to use sys.stdout.write() instead and because without a newline typically no flushing will be done, you should use sys.stdout.flush() explicitly as well.

Then, returning to the first column will not delete the old output, so it only gets overwritten by the next line. If that is shorter than the one before, you will have trailing junk. To avoid this, again use what your terminal provides (very often '\x1b[K' erases everything till the end of the line without moving the cursor, but if this does not work for you, just print some spaces or make sure your output is formatted always to the same width).

EL = '\x1b[K'  # clear to end of line
CR = '\r'  # carriage return
sys.stdout.write(("%d hours %d minutes %s seconds" + EL + CR) % (h, m, s))
sys.stdout.flush()

A more decent approach (besides this shortcut by using literal sequences) is to use the official curses library.

import curses
curses.setupterm()
EL = curses.tigetstr('el')
CR = curses.tigetstr('cr')

And if CR really does not work on OSX as we want it to, then there might be goto in your termcaps to go to a specific position (e. g. first column) or you can use save_cursor (SC) and restore_cursor (RC) to restore an earlier saved position:

sys.stdout.write(SC + "%d hours %d minutes %s seconds" + EL + RC % (h, m, s))
Alfe
  • 56,346
  • 20
  • 107
  • 159
2

Try this:

print h, "hours", m, 'minutes', s, 'seconds', '\r'

and you should also look at Alfe's answer :-)

YS-L
  • 14,358
  • 3
  • 47
  • 58
  • 3
    Add a comma after '\r' so that the next print will go to the same line – Don Feb 05 '14 at 10:28
  • There are other issues with this answer. Using only `'\r'` will add a stray space at the next output, and it won't flush the output. Also trailing junk may occur if the old line is longer than the new one. See my answer for details on how to avoid this. – Alfe Feb 05 '14 at 10:37
2

In Python 3 you could use this kind of code:

print("{} hours, {} minutes, {} seconds".format(h, m, s), end = "\r")
DomTomCat
  • 8,189
  • 1
  • 49
  • 64