CRってなんだ?Pythonでプログレスバーを作り、ターミナル上に表示してみよう。
インフラチームの齊藤です。
今日は、キャリッジリターンについて知っていただき、いくつかスクリプトを書いてみましょう。
次に、Pythonでキャリッジリターンを使用し、プログレスバーを作成してみます。
キャリッジリターン(CR)とは
キャリッジリターン(CR)とはrで表される特殊記号です。改行文字nならご存じの方も多いと思います。
キャリッジリターンとはなんでしょうか。
元々はタイプライターを使用する際に、文字を印字するキャリッジと呼ばれる部分を手で戻して使う動作をキャリッジリターン(carriage return: CR)といいます。
また、新しい行へ移動する動作はラインフィード(line feed: LF)といいます。
今日まで使用されているすべてのOSは電子タイプライタとの互換性を考慮していた歴史があり、この'r'が何らかの形で登場します。
たとえば、WindowsOSであれば、改行はrnです。これは「一度元の位置に戻って(CR)から、新たな行へ移動する(LF)」と解釈できます。
Unix, Mac, Linux, BSDなどは、POSIXという規格に基づきrとnは別々に使用します。
改行文字nを使用した時は、新たな行の先頭へカーソルが設定されます。
つまり、nはCRとLFを両方合わせた役割を持っています。一方でrはカーソルを元の場所へ戻すCRの役割を持っています。
rを使ってみる
OS別に例を挙げましたが、プログラミング言語上でも、rとnは分けて使うことが多いです。
実際にpythonでrを使用してみましょう。
$ python -c "import sys; sys.stdout.write('beyondrBn')" Beyond
・「-c」はpythonでワンライナーを書くためのオプションです。
・sys.stdout.writeで標準出力を行い、文字列はバッファ(キャッシュ)に書き込まれます。
さて、'beyondrBn'では、どういう流れで表示結果が決まるかというと、
1.はじめに文字列は、beyondを表示します。このとき、カーソルはdの後にあります。
2.rがあるのでカーソルはbの先頭に移ります。
3.今度はBをbに被せて印字します。
4.nがあるので改行します。
このように、rは何度も同じ行に文字を書き込むことができます。
プログレスバーを作成する
上記の特性を利用して、コマンドライン上で動くプログレスバーを作成できます。以下はpythonで書いたプログレスバーです。
import sys, time def prog_bar(length=100): for i in range(length): sys.stdout.write('#'*i + 'r') sys.stdout.flush() time.sleep(0.01) for i in range(4): prog_bar()
sys.stdout.writeは、ターミナルに表示を行う前にキャッシュしています。
(実はprint()は、内部でsys.stdoutを使用しています。)
sys.stdout.flushを用いることで、キャッシュされた情報を削除しています。
アニメーションを書いてみる
くるくるバーが回転する楽しいアニメーションも書いてみましょう。(以下はpython3で動作確認済です)
import time space = '.' bar = '-|/' length = 100 printset = (('{0}{1}r'.format (space*(i-length//2) if i > length//2 else '', bar[i%4]), time.sleep(0.05)) for i in range(length)) for i in printset: print(i[0], end='') print(' '*length, end='r')
ほかにも色々な用途に使えます。
私は、パスワードを生成するスクリプトに、スロットのようなアニメーションをつけてみたりもしています。
是非拡張して遊んでみてください。