0

Good afternoon. I have code in Python:

while (time.time() - start_time) < 10:
    current_date_time = time.strftime("%Y-%m-%d %H:%M:%S")
    current_time = time.strftime("%H:%M:%S")

    print("\r" + current_date_time)
    print(current_time, end="\r")
    
    time.sleep(0.5)

I want to get:

cycle1:
line1: data1
line2: data2
cycle2:
line1: data3
line2: data4
...
cycleN:
line1: dataN
line2: dataN+1

but i have now only:

2023-05-12 14:25:24 (data1)
2023-05-12 14:25:25 (data3)
2023-05-12 14:25:25 (data5)
2023-05-12 14:25:26 (data6)
14:25:26 (data7)

The problem is print1 which is not overwrited (i can not get back 1 line UP). How can i correct the code to get desired result?

Thank you in advance for help the newbie.

I try to use print(..., end='') or print(..., end='/r').

I want to get:

cycle1:
line1: data1
line2: data2
cycle2:
line1: data3
line2: data4
...
cycleN:
line1: dataN
line2: dataN+1

===========================================================

My solution code:

import datetime
import time
import colorama
from colorama import Fore, Style

def main():
    # Initialize colorama
    colorama.init()

    # Get the current time
    start_time = time.time()
    
    # Set cycle time length in seconds
    cycle_length = 10

    while (time.time() - start_time) < cycle_length:
        # Get the current date and time
        now = datetime.datetime.now()
        date_time_str = now.strftime("%Y-%m-%d %H:%M:%S")
        time_str = now.strftime("%H:%M:%S")

        # Clear the screen
        print("\033c", end="")

        # Print the date and time
        print(Fore.GREEN + date_time_str)
        print(Fore.YELLOW + time_str)

        # Sleep for 500 milliseconds
        time.sleep(0.5)

        # Clear the date and time
        print("\033[2K", end="")
        print("\033[F", end="")
        print("\033[2K", end="")
        print("\033[F", end="")

        # Sleep for 500 milliseconds
        time.sleep(0.5)

        # Wait for a key press to exit
        if time.time() - start_time >= cycle_length:
            # Clear the first line (stayed after exit before CLI)
            print("\033[2K", end="")
            print("\033[F", end="")
            break

    # Reset colorama
    colorama.deinit()

if __name__ == "__main__":
    main()
Olga
  • 1
  • 2
  • See: https://stackoverflow.com/questions/11474391/is-there-go-up-line-character-opposite-of-n – slothrop May 12 '23 at 13:16
  • Does not help me. or i use it incorrectly: print("\033[F" + "\r" + current_date_time) print(current_time, end="\r") – Olga May 12 '23 at 13:29

2 Answers2

0

I'm not sure what your problem is but what i understood was that you need to overwrite your string. This can easily be done with by adding "\033[F" before the string you're printing.

Example:

print("1")
print("2")
 
# Output:   
# 1
# 2
print("1")
print("\033[F"+"2")
 
# Output:   
# 2

So you can try this:

print("\r" + current_date_time)
print("\033[F"+current_time, end="\r")

For more info :

Welozbee
  • 45
  • 6
  • Does CPL ('\033[F') work on Windows? – DarkKnight May 12 '23 at 15:27
  • Thank you. But the result is not i want (i need to overwrite BOTH prints): 2023-05-12 17:49:09 2023-05-12 17:49:09 2023-05-12 17:49:10 2023-05-12 17:49:10 ←[F17:49:10 – Olga May 12 '23 at 15:50
0

There is an ANSI escape sequence for "Cursor Up" but you can avoid having to use that providing you don't emit a newline character ('\n').

If you use print() then you can suppress newline by specifying end=''

Another option is to write to sys.stdout. In that case there's no extra output added to what ever you provide.

Here's a very simple clock that runs for a period of time (approximately the number of seconds given as the range limit).

One nicety is to turn off the cursor but you need to remember to turn it on again. Hence the try/finally so that even if the program is interrupted (e.g., Ctrl-C) the cursor will still be re-enabled.

from datetime import datetime
from time import sleep
from sys import stdout

ESC = '\x1B' # escape
CSI = f'{ESC}[' # control sequence introducer
EL = f'{CSI}K' # erase in line
CURSOR_OFF = f'{CSI}?25l'
CURSOR_ON = f'{CSI}?25h'

NOW = lambda: datetime.now().strftime('%H:%M:%S')

try:
    stdout.write(CURSOR_OFF)
    for _ in range(5):
        stdout.write(f'\r{EL}{NOW()}')
        sleep(1)
finally:
    print(CURSOR_ON) # use print here because we want newline now

Simplified version for terminals that do not support ANSI escape codes. This will not turn off/on the cursor. It also relies on the output always being of the same length which, in this case, it will be:

from datetime import datetime
from time import sleep

NOW = lambda: datetime.now().strftime('%H:%M:%S')

for _ in range(5):
    print(f'\r{NOW()}', end='')
    sleep(1)
print()
DarkKnight
  • 19,739
  • 3
  • 6
  • 22
  • Thank you. This code is very difficult for me now. If possible, please, write simple solution – Olga May 12 '23 at 15:53
  • @Olga Did you try running this code? Does it do something similar to what you're trying to achieve? – DarkKnight May 12 '23 at 15:58
  • i tried your code and get only one string with incorrect symbols: ←[K19:22:49←[?25h – Olga May 12 '23 at 17:25
  • @Olga That's unfortunate. That means that your terminal (or wherever your standard output stream is directed to) does not support ANSI escape codes. I will add a simplified version – DarkKnight May 12 '23 at 17:26
  • Thank you again. It works good with 1 string. Is it possible to update code to 2 strings (overwrite both)?: 1. Date and time 2. Date – Olga May 12 '23 at 19:27
  • @Olga If you want 2 strings on the same line you just have to change the f-string but don't forget the caveat about the string length. If you want to handle 2 strings each on a separate line then you'll need a "cursor up" ability which it seems your terminal does not have (i.e., doesn't support ANSI escape sequences) – DarkKnight May 13 '23 at 05:06