先日、
12日の記事
にてレイアウトについて書きました。その中でformat関数について触れたので、今回はその使い方について書こうかなと思います。
Pythonを使用するとターミナル上で処理の結果を取得することができますが、この際に
■ input関数
■ print関数
を使用することで
■ 値の入力
■ 値の表示
を行えるようになっています。コーソールでは、文字の入力しかできないので、デスクトップアップリのようにフォントサイズの異なる文字列を画面内に並べることはできません。
その為、基本部分はプレーンテキストの入力と同じになりますが、テキストエディタとは異なり、表示のコントロールが行えます。
コンソールで表示を行う場合にも様々な処理が行えるようになっているので、今回は、そういった内容について書こうかなと思います。
コンソールと表示
コンソールアプリを作る場合、
■ 基本はプレーンテキスト
■ 画像は使用できない
■ 文字の表示のみ
■ 1文字入力ができない場合がある
と言う条件が存在しています。例えば、HTMLの制御用のスクリプト言語のJavaScriptでは、Pythonのinput関数のようなものが存在しません。
その為、定数の指定を行ってコードを書いて処理の確認をすることはできますが、変数の入力を行って表示するような処理をコンソールのみで行うことができません。その為、JavaScriptでは、入力はエレメントを使用した状態で処理をする必要があります。
通常のプログラミング言語の場合だと、コンソールで動くことが基準になっており、ウィジェットなどの利用はオプション扱いですから、プログラミング言語によっては、QtやGTKなどを用意して使用する必要があります。
その為、多くのプログラミング言語で
■ print
■ input
のような入力が存在していますが、BASICの場合だと、
■ 数字 : inkey
■ 文字 : inkey$
で判定を行い、keypressのような 【 1文字入力 】 に対応しているものもあります。当然、inputも存在していますが、コンソール上での処理として入出力は標準機能として用意されています。
多くのプログラミング言語でコンソール上に表示を行う場合には、それに準じたものを使用しますが、C言語だと 【 printf関数 】 を使用することになります。C++でもstdio.hを使用するとC言語と同じ記述を使用できますが、C++ではiostreamを使用するのでストリームの表記になります。この際に、ネームスペースを使用して処理の判断をしているので、処理の先頭にstd::のような識別用の記述が追加される仕組みになっています。その為、C++で表示を行う場合には、
std::cout<< 表示する内容 <<std::endl;
のような表記になります。ネームスペースも複雑なコードに生ると省略すると問題が出るので、解消するような記述を行うことになりますが、ネームスペースの識別用の記述はusingで省略できるようになっています。
このようにプログラミング言語によって表示の記述が異なるもののコンソールで表示を行う際には、仕様にあった記述を用いると表示を行うことができるようになっています。
この際に、コンパイル型言語の場合、コンソールでも複雑な記述に生るものが存在していますが、JAVAの場合、
■ クラス
■ 関数
・処理
・戻り値
のような階層で構造を作る必要があるので、最初に用意するものは関数ではなく、 【 クラス 】 になります。
また、この時にアクセス方法の指定を行う記述も存在しているので、JAVAの場合、かなり厳格な指定を行うような記述方法になっています。
C言語やC++の場合、
■ 関数
・処理
・戻り値
なので、関数の構造を作るだけで済みますが、この2つのプログラミング言語の場合、メモリーの管理が必要なので、
■ 初期化
■ メモリーの開放
を行う必要があり、バッファオーバーフローにならないようにメモリーの管理が必要になります。C言語の場合、Nullになるまで値を格納できてしまう仕様になっているので、変数の型の範囲外までデータを書き込めてしまう仕様になっていますから、
コードに問題がなく処理に問題がある物
でもビルドして実行できてしまう
と言う特徴があります。これは、どのプログラミング言語でもバグが生じていればこの状態になってしまうわけですが、この問題が変数周りで発生する特徴があります。
その為、変数を使用する場合は、不要になった値を格納する必要がないので、開放することになりますが、そのまま記録をしていくと処理時応じて使用しないデータが無駄に容量を消費することになります。
こうした問題を解消するために、データの管理をしっかりと行う必要があるわけですが、C言語やC++だとこの仕組みを構造体やクラスでに組み合わせて考える必要があるので、少し難しくなっています。
Pythonの場合だと、ガーベージコレクターと言う機能があるので、一括消去ができたり、自動管理ができるようになっていますが、ガーベージコレクターを実行してメモリーの開放(メモリー内の変数の消去)を行うこともできるようになっています。
このようにプログラミング言語で記述を行う際の構造や仕組みが異なりますが、Pythonの場合だと、組み込み関数をしよする時にライブラリの読み込みをせずに、収録されているものをそのまま実行できるので、
■ input関数
■ print関数
も
a=input('入力してください_ ')
print('値は'+a+'です。')
のような表記で実行できます。コードは関数などのようにブロック内の場合だとインデントを追加する必要があるので、空白(テキストエディタの場合だとtabキーでも問題ありません。)を指定することになりますが、通常の処理は空白を入れずに入力をすることになります。
このようにprint関数はそのまま使用できるので、用意された文字列を表示するだけだと、print関数のみで処理を行うことができます。
表示と変数
print関数は引数の内容を表示するようになっていますが、引数は定数で指定することができるので、
■ print(数値)
■ print('文字列')
のような使い方ができます。これが定数での指定になりますが、数学でも
1+1=2
を
A+A=2
のように置き換えることができます。この場合、同じ変数を足して2になっているので、A=1となりますが、このように定数の部分は変数に置き換えることができます。変数を使用すると関数のようなことができるので、
f(x)=3x+9
のような記述ができますが、この場合、変数xに値を代入すると海を求めることができるので、
f(10)
とすると39になります。
関数の場合、【 法則性を示した式 】なので、変数の値で解が変化しますが、print関数も関数と同じように定数部分を変数に変更することができます。その為、
a='Hello,Python!'
print(a)
のようにすると、 Hello,Python! と表示されます。
これが、引数に変数を代入した場合の処理になりますが、この状態だと、【 左詰め 】でそのまま文字列が表示されます。
テキストエディタでは、
■ タブの指定
■ 改行
が行えますが、エスケープシーケンスを使用するとprint関数でもそれを使用して表示を行うことができます。
■ エスケープシーケンス
エスケープシーケンスを使用すると特殊な処理を使用できるのですが、環境によっては【 ベル文字 】 を使用することで音を鳴らすこともできます。
その為、
■ 配置
■ 音
の指定をprint関数だけで行えるようになっています。(ベル文字を使う場合だとブザーが必要になると思います。)
タブと改行については、
■ タブ : \t
■ 改行 : \n
になりますが、WINDOWSの場合だと、¥tと¥nになります。Linux環境だと上記のものになりますが、これを表示する文字列に追加するとタブと改行画がいります。例えば、
a='\t'
b='Hello,Python!'
c='\n'
d=c+a+b+c
print(d)
のようにすると、改行後に行の先頭にタブを追加した記述が行われ、文字列の最後に改行が入った状態で表示されます。
実際のコードが
になりますが、これを実行すると
のようになります。
タブを挿入するとタブの前の文字数を合わせてあれば同じ文字数分の間隔を開けることができますが、タブは空白でしかないので、この状態だと 【 常に左揃え 】 になってしまいます。その為、
■ 左揃え
■ 中央揃え
■ 右揃え
と言った処理を実装することができません。
この時に使用するのが 【 format 】 メソッドになります。
formatメソッド
文字を揃えると言ってもカスケードシートのようにピクセル単位で合わせることができるわけではないので、あくまでも文字の位置調整になりますが、formatメソッドを使用すると表示をコントロールできるようになります。
と言っても、
■ 制御部分 : {}
■ データ部分 : ()
に分かれているので、formatメソッドの引数で全てが行えるようになっているわけではありません。formatメソッドは、pirnt関数で衣装することができますが、
print(\
'{}'\
.format(引数))\
)
のような形で表記することができます。ここでは文字数が多いので、\で改行を入れていますが、左側のスーペースを除去するとこの記述でもコードとして実行できます。
コードが長くなった場合、改行する場所に\を入れることで改行をして続きを書くことができるので、コードの文字数が長くて読みにくい場合にはこうした記述を行うことで処理を見やすくすることができます。この記述にすると、
■ 表 示 : '{}'
■ データ : .format()
になっており、この構造物がprint()の中に包含されていることが解ると思いますが、この構造にすると、引数の内容を{}の中に代入することができます。
この構造は、C言語の、
■ 代入演算子
■ 変数
の構造にして、変数を文字列の中に代入するのと似た構造になっていますが同じような使い方ができます。
上記のコードを
print(\
'{}'\
.format('TEST'))\
)
のようにすると、{}は引数を参照しますから、TESTと表示されます。
この事例では引数が1つしかりませんが、
print(\
'{}-{}'\
.format('TEST','test')\
)
のように引数が2つある事例だと、{}の中には、順番に引数が代入されるので、
'{第一引数}-{第二引数}'\
が代入されます。この参照する引数もインデックスで選択ができるので、
print(\
'{}-{}'\
.format('TEST','test')\
)
print(\
'{0}-{0}'\
.format('TEST','test')\
)
print(\
'{1}-{1}'\
.format('TEST','test')\
)
のように指定すると、指定した値を使用することができます。
実際に
のようにコードを書いて実行すると
のように参照している引数の値が変化しています。
データの配置
通常のprint関数で文字を並べると文字数が異なるとレイアウトが破綻しますが、formatメソッドを使用すると、コンソール上でもレイアウトを綺麗に整えることができます。
文字をレイアウトする場合、
■ 範囲
■ 文字数
が存在しますから、
【 文字数の最大値を基準に考える 】
ことになります。これを行うと、帳票のような構造であっても、枠の範囲が決まっているので、次の文字はその枠の向こう側からレイアウトすることができます。この時に、{}内の記述を行うことになりますが、リストや引数のインデックスを使う場合、
{インデックス:最大文字数}
の指定を行うと、文字数で区画を指定して、その中に文字を配置することができます。基本は通常の表示と同じ左揃えになりますが、
{0:10}
のようにすると、10文字のセルを用意してその中に引数で参照した文字を表示することになります。考え方としては、
■ n : データの文字数
■ m : 文字数の最大値
とした場合 【 m > n 】 になるように数値を指定することになります。データの文字数はlenで取得できるので、
【 len(n) < m 】
になるように区画の調整をすることになります。つまり、余白をaとした場合、
【 m = len(n) + a 】
のようにすれば、文字が区画の範囲を超過することがなくなります。
アライメント
{}の中の記述を変更するだけで代入する区画をスプレッドシートのセルのように扱うことができるようになりますが、この時に数字の前に記号を追加することで、一の調整を行うことができます。
と言っても、行野中の出来事を文字数で行っているだけなので、奇数と偶数の組み合わせだとセンタリングがうまく行きませんが、
■ 左揃え
■ 中央揃え
■ 右揃え
の指定ができます。これは、
■ < : 左揃え
■ ^ : 中央揃え
■ > : 右揃え
で行うことができます。コードとしては、
【 左揃え 】
print('{0:^10} : {1:<10}'\
.format('test','100'))
【 中央揃え 】
print('{0:^10} : {1:^10}'\
.format('test','100'))
【 右揃え 】
print('{0:^10} : {1:>10}'\
.format('test','100'))
のようになりますが、実際に
のようなコードを書いて実行すると
のようになります。pythonファイルを実行する際には、
のように
python3 ファイル名.py
のように入力して実行することになりますが、コンソール上では、
のようにプロンプトの後に処理が実行されます。処理が終了するとプロンプトの表示になりますが、これがループなしの処理を実行した時の結果になります。無限ループを入れると終了するまで表示が繰り返されるのですが、画面お初期化を行わない場合には下に処理が追加されていく仕組みになっています。
このデータをリストを参照してループで読み込むとスプレッドシートのように整列した形で表示することができます。
文章の場合だと、区画を指定しておいて、その中に文字列を配置するようにすると読みやすくなるので、ワープロソフトで余白を指定するように文字数と改行でレイアウトをすれば文章を読みやすくなりますが、帳票の場合だと、セルの幅が決まっていたほうが見やすいので、最大の文字数で管理して表示をすると、スプレッドシートで作成した帳票のように整列させることができます。