0

There is some code that displays the function process:

all_nums = 100
counter = 0

def status(num, counter):
    print(
        f'Current number {num}',
        f'Numbers done: {counter}, all nums: {all_nums}',
        f'{(num/all_nums):2.1%}',
        flush=False, end='\r'
    )


for x in range(all_nums):
    counter += 1
    status(x, counter)
    time.sleep(0.1)

It works. But I want to split this text on a line. When I add \n to any place everything breaks.

Current number 1, all nums: 100 0.0%
Current number 2, all nums: 100 1.0%
Current number 3, all nums: 100 2.0%
Current number 4, all nums: 100 3.0%

How can I overwrite console output in multiple lines?

kshnkvn
  • 876
  • 2
  • 18
  • 31
  • @Carcigenicate I wrote it clearly: the code works fine until you add line breaks, after that it starts working like a regular print, i.e. does not change the line, but prints a new one. – kshnkvn Oct 10 '19 at 12:19
  • 1
    Please clearly show the current output and the expected output, that makes it much easier for us to understand what you want – Energya Oct 10 '19 at 12:23
  • @Energya how i can do that? This function modifies the output string. Should I record a video to show how it works? – kshnkvn Oct 10 '19 at 12:26
  • I ran your code and all output stayed resident on the same line. My environment is bash on Ubuntu. Could your environment be part of the problem? – jhelphenstine Oct 10 '19 at 12:27
  • @jhelphenstine do you run it with linebreak, for example here: f'Current number {num}\n', ? – kshnkvn Oct 10 '19 at 12:28
  • I think @kshnkvn would like to be able to add line breaks between e.g. current number and numbers done and yet be able to clear those lines when the count increments. Right now, it works when the strings do not have `\n` –  Oct 10 '19 at 12:30
  • You may have to clear the console by `os.system('cls')` on windows and perhaps `os.system('clear')` elsewhere. –  Oct 10 '19 at 12:31
  • @JustinEzequiel so i must all time clear outp and print again? – kshnkvn Oct 10 '19 at 12:33
  • `\r` (carriage return IIRC) moves the insertion point to the start of the current line which would be the last line if you have multiple `\n` (line feed) characters. So yes, you'll need to clear the console somehow to do what you want. –  Oct 10 '19 at 12:35
  • @kshnkvn I ran it as you wrote it, on both linux & windows, and it works as you intend it to -- all output stays on the same line. edit -- at the end, the next command prompt line overwrites this one, but that could be addressed with a simple print() after your function call. – jhelphenstine Oct 10 '19 at 12:38
  • See this [SO discussion](https://stackoverflow.com/questions/6840420/python-rewrite-multiple-lines-in-the-console). –  Oct 10 '19 at 12:48

3 Answers3

1

Use some ANSI escape codes to control your terminal: (from https://stackoverflow.com/a/11474509/8733066) "\033[F" makes the terminal cursor go up one line, *3 is because there are 3 lines

def status(num, counter):
    print("\033[F"*3)
    print(
        f'Current number {num}',
        f'Numbers done: {counter}, all nums: {all_nums}',
        f'{(num/all_nums):2.1%}',
        sep="\n"
    )

# call this before the for loop:
print("\n"*3, end="")
bb1950328
  • 1,403
  • 11
  • 18
0

Simply update status function with:

def status(num, counter):
    print(f'''Current number {num}
Numbers done: {counter}, all nums: {all_nums}
{(num/all_nums):2.1%}''')
    sys.stdout.write("\033[F"*3) # Cursor up 3 lines

and

import sys
-1
all_nums = 100
counter = 0

def status(num, counter):
    print(
        f'Current number {num}',
        f'Numbers done: {counter}, all nums: {all_nums}',
        f'{(num/all_nums):2.1%}',
        flush=False, end='\r'
    )
    print()


for x in range(all_nums):
    counter += 1
    status(x, counter)
    time.sleep(0.1)
Daniel
  • 1
  • 1