2

I'm trying to print strings in one line.

I've found solutions but they don't works with windows correctly.

I have text file contains names and I want to print them like this

name=john then change john to next name and keep name=, I've made this code but didn't work correctly with windows:

op = open('names.txt','r')
print 'name=',
for i in op.readlines():
    print '\r'+i.strip('\n')

thank you for your time

jsalonen
  • 29,593
  • 15
  • 91
  • 109
Hamoudaq
  • 1,490
  • 4
  • 23
  • 42

2 Answers2

5

Simply using \r won't work in this case, because that returns you to the beginning of the line, so you'll have to reprint the entire line. Also, in some systems (including Windows, I think) Python's print statement (function in 3+) interprets \r as a newline. I believe this code should be system-independent.

import sys, time

with open('names.txt', 'r') as names:
    prev_len = 0
    for name in names:
        sys.stdout.write('\r' + ' ' * prev_len)
        sys.stdout.flush()
        output_string = '\rname={}'.format(name.strip())
        prev_len = len(output_string)
        sys.stdout.write(output_string)
        sys.stdout.flush()
        time.sleep(0.3)
print

You could also use \b, which generally moves the cursor back by one space.

As you pointed out, it's necessary to overwrite the previously printed line with spaces, which means it's necessary to remember the length of the previous line. It makes sense to encapsulate that state in an object, I think. Here's a much cleaner solution than the above that uses that strategy:

import sys, time

class LineUpdater(object):
    def __init__(self, outfile=None):
        self.prev_len = 0
        self.outfile = sys.stdout if outfile is None else outfile

    def write(self, line):
        line = line.strip()
        output = '\r{:<{width}}'.format(line, width=self.prev_len)
        self.prev_len = len(line)
        self.outfile.write(output)
        self.outfile.flush()

with open('names.txt', 'r') as names:
    out = LineUpdater()
    for name in names:
        out.write('name={}'.format(name))
        time.sleep(0.3)
    print
senderle
  • 145,869
  • 36
  • 209
  • 233
  • sir your code doesn't works correctly with windows ,, the issue is if you printing long name for example `naaaaaaaaaaaaame` then next name would be `john` the output would be like `johnaaaaaaaaaame` i've tried your solutions before i post this problem and didn't work with windows – Hamoudaq Jun 16 '12 at 14:34
  • Ah! Of course -- `\r` is usually used to print lines of equal length. This wouldn't work on any system for your purposes! I'll update. – senderle Jun 16 '12 at 14:37
  • @EngHamoud, see my edit. The new code should work correctly. There may be a better way to do it, but it works at least! – senderle Jun 16 '12 at 14:48
  • yes it works thank you verrrry much ,, but really its little bit kludge , thank you anyways i'll try to find out more appropriate way – Hamoudaq Jun 16 '12 at 14:52
  • @EngHamoud, see my most recent edit for what I think is the cleanest solution. – senderle Jun 16 '12 at 15:07
1

Using '\b' as suggested by senderle

import sys
import time

sys.stdout.write('name=')
last_lenght = 0
with open('names.txt') as names:
    for name in names:
        sys.stdout.write('\b' * last_lenght)    # go back
        sys.stdout.write(' ' * last_lenght)     # clear last name
        sys.stdout.write('\b' * last_lenght)    # reposition
        sys.stdout.write(name.strip())
        sys.stdout.flush()
        last_lenght = len(name.strip())
        time.sleep(0.5)
Facundo Casco
  • 10,065
  • 8
  • 42
  • 63