programing

Python에서 콘솔 출력 바꾸기

lastmoon 2023. 7. 16. 17:44
반응형

Python에서 콘솔 출력 바꾸기

특정 C/C++ 프로그램처럼 파이썬에서 멋진 콘솔 카운터 중 하나를 어떻게 만들 수 있는지 궁금합니다.

작업을 수행하는 루프가 있으며 현재 출력은 다음과 같습니다.

Doing thing 0
Doing thing 1
Doing thing 2
...

마지막 라인 업데이트만 하는 것이 더 나을 것입니다.

X things done.

저는 이것을 여러 콘솔 프로그램에서 보았는데 Python에서 이것을 할 수 있는지/어떻게 할 수 있는지 궁금합니다.

쉬운 해결책은 그냥 쓰는 것입니다."\r"문자열 앞에 새 줄을 추가하지 않고 문자열이 더 짧아지지 않으면 충분합니다.

sys.stdout.write("\rDoing thing %i" % i)
sys.stdout.flush()

조금 더 세련된 것은 진행 표시줄입니다...이것은 제가 사용하는 것입니다.

def start_progress(title):
    global progress_x
    sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41)
    sys.stdout.flush()
    progress_x = 0

def progress(x):
    global progress_x
    x = int(x * 40 // 100)
    sys.stdout.write("#" * (x - progress_x))
    sys.stdout.flush()
    progress_x = x

def end_progress():
    sys.stdout.write("#" * (40 - progress_x) + "]\n")
    sys.stdout.flush()

호출start_progress작업에 대한 설명을 전달합니다.progress(x)어디에x이 백분율이고 마지막으로end_progress()

보다 우아한 솔루션은 다음과 같습니다.

def progress_bar(current, total, bar_length=20):
    fraction = current / total

    arrow = int(fraction * bar_length - 1) * '-' + '>'
    padding = int(bar_length - len(arrow)) * ' '

    ending = '\n' if current == total else '\r'

    print(f'Progress: [{arrow}{padding}] {int(fraction*100)}%', end=ending)

이 함수를 다음과 같이 호출current그리고.total:

progress_bar(69, 100)

결과는 다음과 같습니다.

Progress: [------------->      ] 69%

참고:

python 3에서는 다음과 같이 동일한 줄에 인쇄할 수 있습니다.

print('', end='\r')

특히 최신 업데이트 및 진행 상황을 추적하는 데 유용합니다.

루프의 진행 상황을 보고 싶다면 여기서 tqdm추천합니다.현재 반복 및 전체 반복을 예상 완료 시간과 함께 진행 막대로 인쇄합니다.매우 유용하고 빠릅니다.python2 및 python3에서 작동합니다.

저는 얼마 전에 이것을 썼고 그것에 대해 정말 행복합니다.자유롭게 사용하세요.

시간이 걸립니다.index그리고.total그리고 선택적으로title또는bar_length완료되면 시간 유리를 체크 표시로 바꿉니다.

⏳ Calculating: [████░░░░░░░░░░░░░░░░░░░░░] 18.0% done

✅ Calculating: [█████████████████████████] 100.0% done

테스트를 위해 실행할 수 있는 예제를 포함했습니다.

import sys
import time

def print_percent_done(index, total, bar_len=50, title='Please wait'):
    '''
    index is expected to be 0 based index. 
    0 <= index < total
    '''
    percent_done = (index+1)/total*100
    percent_done = round(percent_done, 1)

    done = round(percent_done/(100/bar_len))
    togo = bar_len-done

    done_str = '█'*int(done)
    togo_str = '░'*int(togo)

    print(f'\t⏳{title}: [{done_str}{togo_str}] {percent_done}% done', end='\r')

    if round(percent_done) == 100:
        print('\t✅')


r = 50
for i in range(r):
    print_percent_done(i,r)
    time.sleep(.02)

또한 터미널 폭에 따라 반응형 진행 표시줄이 있는 버전이 있습니다.shutil.get_terminal_size()그것이 흥미로운 일이라면

시스템 라이브러리를 사용하지 않고도 수행할 수 있습니다.print()기능.

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

내 코드는 다음과 같습니다.

def update(n):
    for i in range(n):
        print("i:",i,sep='',end="\r",flush=True)
        time.sleep(1)

(나처럼) 몇 년 후에 이 문제를 해결하는 사람들을 위해, 저는 6502의 방법을 약간 수정하여 진행률 표시줄이 감소하고 증가할 수 있도록 했습니다.약간 더 많은 경우에 유용합니다.6502 훌륭한 도구에 감사드립니다!

기본적으로 유일한 차이점은 진행률(x)이 호출될 때마다 #s와 -s의 전체 라인이 기록되고 커서는 항상 막대의 시작 부분으로 돌아간다는 것입니다.

def startprogress(title):
    """Creates a progress bar 40 chars long on the console
    and moves cursor back to beginning with BS character"""
    global progress_x
    sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41)
    sys.stdout.flush()
    progress_x = 0


def progress(x):
    """Sets progress bar to a certain percentage x.
    Progress is given as whole percentage, i.e. 50% done
    is given by x = 50"""
    global progress_x
    x = int(x * 40 // 100)                      
    sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41)
    sys.stdout.flush()
    progress_x = x


def endprogress():
    """End of progress bar;
    Write full bar, then move to next line"""
    sys.stdout.write("#" * 40 + "]\n")
    sys.stdout.flush()

다른 대답이 더 나을 수도 있지만, 제가 하고 있던 것은 이렇습니다.먼저 백스페이스 문자를 출력하는 프로그레스(progress)라는 기능을 만들었습니다.

def progress(x):
    out = '%s things done' % x  # The output
    bs = '\b' * 1000            # The backspace
    print bs,
    print out,

그리고 나서 저는 제 주요 기능에서 그것을 고리 모양으로 불렀습니다.

def main():
    for x in range(20):
        progress(x)
    return

이렇게 하면 당연히 전체 줄이 지워지지만, 원하는 작업을 수행하기 위해 줄을 잘못 사용할 수 있습니다.저는 이 방법을 사용하여 진행 표시줄을 만들었습니다.

내가 잘 이해했다면(잘 모르겠다) 다음을 사용하여 인쇄할 것입니다.<CR>그리고 아닌<LR>?

이 작업이 가능한 경우 콘솔 단말기에서 허용하는 한 이 작업이 수행됩니다(출력 si가 파일로 리디렉션되면 중단됨)

from __future__ import print_function
print("count x\r", file=sys.stdout, end=" ")

Aravind Voggu의 예에 기능이 조금 더 추가되었습니다.

def progressBar(name, value, endvalue, bar_length = 50, width = 20):
        percent = float(value) / endvalue
        arrow = '-' * int(round(percent*bar_length) - 1) + '>'
        spaces = ' ' * (bar_length - len(arrow))
        sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\
                         name, width, arrow + spaces, int(round(percent*100))))
        sys.stdout.flush()
        if value == endvalue:     
             sys.stdout.write('\n\n')

이제 이전 진행 표시줄을 바꾸지 않고 여러 진행 표시줄을 생성할 수 있습니다.

▁added다니습도 추가했습니다.name너비가 고정된 값입니다.

두 번의 루프 및 두 번의 용도progressBar()결과는 다음과 같습니다.

progress bar animation

from time import sleep

max_val = 40

for done in range(max_val):
    sleep(0.05)

    undone = max_val - 1 - done
    proc = (100 * done) // (max_val - 1)
    print(f"\rProgress: [{('#' * done) + ('_' * undone)}] ({proc}%)", end='\r')

print("\nDone!")
Progress: [###################_____________________] (47%)
Progress: [########################################] (100%)
Done!

아래 코드는 0.3초마다 이전 번호를 대체하는 0부터 137까지의 메시지를 카운트합니다.

백스테이지에 대한 기호 수 = 자릿수.

stream = sys.stdout
for i in range(137):
    stream.write('\b' * (len(str(i)) + 10))
    stream.write("Message : " + str(i))
    stream.flush()
    time.sleep(0.3)

같은 문제가 있었고 많은 해결책을 시도했습니다.

import sys 
sys.stdout.write('\r Blablabla')

매력적으로 작동했습니다!

언급URL : https://stackoverflow.com/questions/6169217/replace-console-output-in-python

반응형