3

Let's say I have a counter that counts from 0 to 100000. I don't want all the numbers showed, I just want to see the number we are at end the % of completion.

I know that if I want to rewrite over the line, I must add \r at the beginning. However, if I want to do this on two lines, how am I supposed to do that ?

1
0.001%

then

2
0.002%

Also, let's say I want to add new lines for the numbers, but always keep the percentage at the bottom like this:

1
2
3
4
5
6
7
8
0.008%

Do you have any idea on how to achieve that?

Here is my code so far (doesn't work, obviously):

from sys import stdout

for i in range(100000):
    stdout.write(str(i) + '\r\n')
    stdout.write('%.2f' % (i / 100000 * 100) + '%\r')
    stdout.flush()

stdout.write('\n')

Thank you !

NicolasSC
  • 368
  • 2
  • 19
  • 1
    You can use the `curses` library, which (fair warning) is aptly named. – tdelaney Apr 10 '20 at 16:46
  • 1
    If you are on a linux machine, there are ways to print an "UP" character and a carriage return to print over existing lines, but that is very system dependent. – callyalater Apr 10 '20 at 16:51
  • I had an answer to a similar question. https://stackoverflow.com/a/60763544 `"\033[F"` is the up char. You may need to erase the previous number fully. Also `\n` is mostly likely sufficient even on windows. – JL Peyret Apr 10 '20 at 16:55

1 Answers1

3

you can use curses module:

import curses

import time
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()


n = 100000
num_lines = 10
lst = list(range(n))
for t in [lst[i:i + num_lines] for i in range(0, len(lst), num_lines)]:
    final_line = f'{t[-1] / n * 100:.4f}%'
    out = '\n'.join(map(str, [*t, final_line]))
    stdscr.addstr(0, 0, out)
    stdscr.refresh()
    time.sleep(0.005)  # you can comment but will be too fast

curses.echo()
curses.nocbreak()
curses.endwin()
kederrac
  • 16,819
  • 6
  • 32
  • 55