2010/11/07

コンソール(ターミナル・シェル)上で改行をさせずに文字を表示する方法(タイマーを作ってみた)

「Python Recipes」に戻る

Release:1.0
Date:November 07, 2010
  テスト環境
  OS: Ubuntu10.10

  Python2.6.6
  Python2.5.2
  Python3.1.2

コンソール(ターミナル・シェルなど)上で改行をさせずに文字を表示する

apt-getやbzrの待ち時間を表すものなどは、コンソール(ターミナル・シェル)上では改行されないで、
表示されています。
これを実現するためには sys.stdout.write()sys.stdout.flush()
使います。
まずは、下のコードを走らせてみましょう。

■Pyrhon2.5とPython2.6
import sys
from time import sleep

wait_time = 1
strings = u"いろはにほへと"

for num, strs  in enumerate(strings):
    disply = "\r%d番目 -->  %s" % (num + 1, strs.encode('utf8'))
    sys.stdout.write(disply)
    sys.stdout.flush()
    sleep(wait_time)
sys.stderr.write('\n')
■Python3.1
import sys
from time import sleep

wait_time = 1
strings = "いろはにほへと"

for num, strs  in enumerate(strings):
    disply = "\r{0}番目 -->  {1}".format(num + 1, strs)
    sys.stdout.write(disply)
    sys.stdout.flush()
    sleep(wait_time)
sys.stderr.write('\n')
「1番目 –> い」 〜 「7番目 –> と」までが、コンソール上で改行されずに表示されたはずです。
もし flush() をしなければ、コンソールにはなにも表示されません。
flush() を使ってきちんと書き出しをしましょう。(※自分もよくわかっていません)

コンソール上で改行させずに1行で表示するコード(タイマー風・メーター付き)

今度は、メーター風の文字を表示させながら残り時間を表示するコードです。

■Python2.6 Python3.1
import sys
from time import sleep

rng_time = 10
wait_time = 1

for i in range(1, rng_time + 1):
    rate = i * 71 // rng_time
    meter = "\r|{0}{1}| {2}秒".format("=" * rate, ' ' * (71 - rate), (rng_time - i))
    sys.stdout.write(meter)
    sys.stdout.flush()
    sleep(wait_time)
sys.stderr.write('\n')
■Python2.5
import sys
from time import sleep

rng_time = 10
wait_time = 1

for i in range(1, rng_time + 1):
    rate = i * 71 / rng_time
    meter = "\r|%s%s| %d秒" % ("=" * rate, ' ' * (71 - rate), (rng_time - i))
    sys.stdout.write(meter)
    sys.stdout.flush()
    sleep(wait_time)
sys.stderr.write('\n')
表示されるのは、
|=======                                                                | 8秒
から、
|=======================================================================| 0秒
のような感じで、改行されずに表示されます。

最終的なコード

待ち時間を受け付けて、上記のコードを足した最終的なコードを見てみましょう。
汚くてすみません、、、
■Python2.6
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#from __future__ import unicode_literals
import sys
import datetime
from time import sleep

def msgs(msg):
    print('*' * 80)
    print(msg)
    dt = datetime.datetime.now()
    print('{year}/{month:#02d}/{day:#02d} '
          '[{hour:#02d}:{minute:#02d}:{second:#02d}]'.format(
              year=dt.year, month=dt.month, day=dt.day, hour=dt.hour,
              minute=dt.minute, second=dt.second))
    print('*' * 80)
    print('\n')

msgs("\tタイマーを作動させます。\n\t時間を入力してください。\n")
print("秒単位で入力してください。\n何秒にセットしますか?\n")
times = int(raw_input("Please input number.\n>> "))
print('\n')
msgs('\t{0}秒にセットされました。\n\t現在時刻は↓ なので時間を見て戻ってきてください。\n'.format(times))

# 残り時間を1行に表示するコード
for i in range(1, times + 1):
    rate = i * 71 / times
    meter = "\r|{0}{1}| {2}秒".format("=" * rate, ' ' * (71 - rate), (times - i))
    sys.stdout.write(meter)
    sys.stdout.flush()
    sleep(1)
sys.stderr.write('\n')

print('\n')
msgs('\t{0}秒経ちました。時間ですよ!!\n'.format(times))

'''
Created on 2010-11-03
@author Iyori Komiyama
'''
下記のように表示されます。
********************************************************************************
    タイマーを作動させます。
        時間を入力してください。

2010/11/07 [23:27:25]
********************************************************************************


秒単位で入力してください。
何秒にセットしますか?

Please input number.
>> 8


********************************************************************************
    8秒にセットされました。
        現在時刻は↓ なので時間を見て戻ってきてください。

2010/11/07 [23:27:28]
********************************************************************************


|=======================================================================| 0秒


********************************************************************************
    8秒経ちました。時間ですよ!!

2010/11/07 [23:27:36]
********************************************************************************

参考・引用・謝辞

Note
■参考・引用:
・ mercurialのkeepalive.py
・ [Python-ml-jp 5061] Re: コンソールに重ね打ちする方法ご存知の方、教えて下さい。
■助けていただいた方たち
ありがとうございました!!感謝です!!

「Python Recipes」に戻る

1 件のコメント:

  1. プログレスバーの参考になりました。(´▽`)アリガト!

    返信削除