0

Context

I have difficulties finding the right stackoverflow question for this purpose: I would like to update a printed line in python with a value that is computed after something else is printed. the something else should stay below the line that is updated.

For example:

first="hello"
third=""
print(f'{first} \r{third}', end=" ", flush=True)

second="somethingelse"
print(second)

if second == "somethingelse":
    third="world"
else:
    third="Universe"

Should print:

hello 
something.

which is then changed to:

hello world
something

Or it should print:

hello
something.

which is then changed to:

hello universe
something

It is important that:

  • hello is printed before something is printed.
  • world/universe is printed on the same line as hello.
  • something is below the hello universe/world line.
  • something can consist of an arbitrary number of printed lines.

XY-problem

I modified the showme pip package to show the runtimes of functions. And I would like the function name to be printed, followed by the output of the function that is being running. And still print the runtime behind/on the same line as the function name. (To reduce the CLI clutter).

Question

How do I update a line with a value that is computed after other stuff is printed below that line?

Related Questions:

Print in one line dynamically

How can I print something, and then call a function with a print on the same line?

Remove and Replace Printed items

How to overwrite the previous print to stdout?

a.t.
  • 2,002
  • 3
  • 26
  • 66
  • 2
    `NameError: name 'third' is not defined` – RomanPerekhrest May 07 '23 at 15:53
  • Thank you, that was deliberate to indicate I do not know what third is going to be at the time of writing the first print statement. Seeing that led to some confusion, I assigned it an empty string to alleviate the error message. – a.t. May 07 '23 at 15:56
  • 1
    Using [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code#Unix-like_systems#:~:text=Some%20ANSI%20control%20sequences%20(not%20an%20exhaustive%20list)), I can half get it to work in a console, using the below. Need to go somewhere, but will check in later.`def printing(): first="hello" third="" print(f'{first} \n{third}', end="\r", flush=True) second="somethingelse" print(second) if second == "somethingelse": third="world" else: third="Universe" print(f'\033[2A{first} \n{third}\033[K') printing()` – bc1155 May 07 '23 at 16:30
  • 1
    The `print()` call is modelled on what happens with paper in a line printer. To do what you want, it would have to print line 1 with *hello* and then line 2 with *something*, then roll back the paper in the printer to print something more on line 1. Line printers can't do that. Like on paper, once it's printed to the console, you can't easily unprint it. You can use ANSI escape sequences, which will work on some consoles, to move the cursor back up the screen. But some versions of Windows don't implement them, and they often won't work as expected in emulated consoles like PyCharm. – BoarGules May 07 '23 at 16:39

2 Answers2

1

Without using curses or something similar, it is only possible to update the last line of output in a terminal and not the previous ones.

Here is a simple example of how to update the first line after printing the second line with curses (sleep function used only to make the changes more obvious):

import curses
from time import sleep

w = curses.initscr()

w.addstr(0,0, 'first line')
w.refresh()
w.addstr(1, 0, 'second line')
w.refresh()

sleep(2)

w.addstr(0,0, 'replaced first line')
w.refresh()

sleep(2)

curses.endwin()
Jarno Lamberg
  • 1,530
  • 12
  • 12
  • Thank you for the suggestion, I am looking into it. Using an external library, or pip package is perfectly fine, as this is also for a custom pip package. – a.t. May 07 '23 at 16:16
  • 1
    I added a simple code example using curses on how to update the first line. – Jarno Lamberg May 07 '23 at 16:34
  • 1
    Magnificent, thank you! It even works with multiple lines inbetween. – a.t. May 07 '23 at 16:45
0

i am not quite sure that this answer would satisfy you

first="hello"
third=""
second="sometfirst="hello"
third=""
second="somethingelse"

if second == "somethingelse":
    third="world"
else:
    third="Universe"
    
print(f'{first} {third}', end=" ", flush=True)
print(second)
Dejene T.
  • 973
  • 8
  • 14
  • Thank you for your effort and suggestion! It is not quite in line with the objective because you print the final value of `third` before you print the value of `second`. – a.t. May 07 '23 at 16:14