第3回 変数の使い方、データの入出力(input, print)

この回の内容

名前を聞いて、あいさつする

どのプログラミング言語のカリキュラムでも、最初に「Hello, World!」という短いプログラムを作るのが、いつどこから始まった風習なのかわからない。
リスト3-1のプログラムは、それをちょっと拡張して、ユーザの名前を訊ね、(オーストラリア風の)あいさつを返す。わずか3行と短いが、データの入出力変数への代入など、一通りの基本を含んでいる。

リスト3-1: hello.ipynb

1行目はコメント(注釈)である。pythonでは、「#」から行末(改行文字)までがコメントとみなされる。コメントは言語処理系ではなく、人間がプログラムを読むためのヒントである。処理系はコメント部分を何もせず読み飛ばす。
このリストに挙げたのは、ひとまとまりのテキストファイルとしてプログラムを書くときの書き方だが、Colabノーツブックではコードセルとテキストセルを使い分けて、リスト3-2のように書く方がよいかもしれない。より長いプログラムを書く時は、コードセルもいくつかに分ける場合が多い。その方が部分的にテストしやすいからだ。

リスト3-2: コードセルとテキストセルでプログラムを書く
input()関数は、画面に「あなたの名前を教えてください:」というプロンプト文を表示し、ユーザがキーボードから名前を打ち込むのを待つ。入力されるまで(Enterキーが押されるまで)、プログラムの「実行点」はinput()関数を出ない。
文字列として入力された名前は、変数name代入される。別のいいかたをすれば、変数nameは、ユーザの名前という文字列をとして持つ。このように変数は、何らかの値(数値や文字列)を格納する器の役割をする※1

1 学校数学で習った「変数」とはかなり異なる。変数xやyは、むしろ方程式や関数式を構成する部品だった。

変数「name」の後の「=」代入を意味する。学校数学で習った等号ではないから注意。後の回で学ぶ条件式(条件分岐や繰り返し構文で用いる)中で、「xは1に等しい」という等式を表現するには、「x == 1」のように書く。つまり、「==」が比較演算子の一種である等号なのだ。
一方、print()関数※2は、文字列や数値などのデータを画面に出力(表示)する。print()関数には、文字列定数('Howdy')や変数(name)、オプション(end = '')を引数(パラメータ)として並べて渡せ、その順に連結されて出力される。文字列中に変数名を記述すると、変数の値に置き換えられる(これを「評価(eval)」という)。より細かく出力形式を指定したいときには、第10回で紹介する「f文字列」などの書式指定構文を用いる。

2 関数も、学校数学の「関数」とはかなり異なる。数学における関数は、「y = 1 / x」のような、「互いに関連して変わる数」を指していた。
また、数学の関数は、パラメータを計算して値を返すだけだが、pythonの関数は、他にいろいろなことをしてくれる場合がある。これを副作用という。input()は副作用としてユーザからの入力文字列を値として受け取るし、print()では副作用の方が重要で、関数が帰す値は使われない(関数である以上なんらかの値は返すはずだが、私を含めて誰も返す値を気にしない)。

全体として、このプログラムは、

  1. ユーザの入力を促す文(プロンプト)を出力
  2. ユーザに名前文字列を入力させ、変数nameに格納
  3. その名前を織り込んだあいさつ文を出力
の順に動作する。プログラムの実行の流れは、1→3の一方通行だ。分岐繰り返しの構文を学ぶまでは、このような単純な流れの処理しか表現できない。

飲み会の勘定清算

最初の「hello.ipynb」では、変数nameがユーザの名前という文字列を値として格納していた。今度は、数値を格納した変数を使って、リスト3-3に挙げる飲み会の勘定精算プログラムを作ってみよう。

リスト3-3: enkai.ipynb

hello.ipynbに比べてプログラムが長いので、注釈をテキストセルに置き、コードセルも分割してみた。長いプログラムは、このようにコードを適切に分割することで、見やすくなり、エラーも修正しやすくなるので、各自工夫すること(ただし、どこででも分割できるわけではない。たとえばif文やwhile文の後の「コードブロック」の途中で分割するとエラーになる)
suzukiやaveなどの変数に代入された数値(金額)が、上のセルから下のセルに引き継がれていることがわかる。
ただし、複数のコードセルからなるプログラムを実行するときは、必ず上のセルから順に実行しなければならない。途中でエラーが発生してセル内のプログラムを修正(デバッグ)した場合も同じである。

aveを浮動小数点数ではなく、整数(つまり1円単位)にするために、除算の演算子に「//」を使うのはなぜか(ヒント:教科書9ページ)
print()関数で、複数の値を出力するために、hello.ipynbとは異なり文字列連結演算子「+」が使われていることに注目。str()は、数値を文字列化する関数である※3。Pythonでは、四則演算で書けない計算などをするため、多くの関数が用意されているし、自分で新たな関数を定義することもできる(第9回を参照)。

3 Perl言語などと違い、数値と文字列を直接連結するとエラーになる。

見慣れない演算子「-=」が並んでいるが、これは「左辺の変数から右辺(の式)を引いた値を新たに左辺に代入する」という意味である。つまり、

suzuki -= ave
suzuki = suzuki - ave
この2つの式は同じ意味である。Pythonに限らず、プログラム中ではこのように、変数の値を更新する処理がたいへん多いので、更新する変数名を左辺と右辺に2回書く手間を省くため、このような演算子が多数用意されている。一部をここに挙げる。他にどんな種類があるか、教科書(14ページ)で調べておこう。
n += 5
加算して代入。「n = n + 5」と同じ
n -= 5
減算して代入。「n = n - 5」と同じ
n *= 2
乗算して代入。「n = n * 2」と同じ
n /= 2
除算して代入。「n = n / 2」と同じ
PerlやCなど多くの言語にあるn++(インクリメント演算子)n--(デクリメント演算子)はない。それらに慣れた身にはちょっと不便だが、読みにくいコードを書かせないことを目指しているのだろうと思って我慢している※4。Pythonでは、それぞれこう書く。

n += 1
n -= 1

4 逆にC系言語では、単項演算子++/--で変数の値を変えられることで、変数の評価(値の取り出し)と増減操作の順序をどうするかという問題が発生する。そこで順序と加減の組合せで、4通りの演算子を区別しなくてはならない。便利と不便は背中合わせなのだ。

Pythonでは、文字列を値とする変数(name)も、整数や浮動小数点数を値とする変数(ave)も特に区別せず、事前の宣言なしで使える。数値が代入されていた変数に文字列を代入しても怒られない。このルーズさ(型付けの弱さ)は一見便利だが、プログラマが自分で変数の種類を意識的に管理しないと、やっかいなバグの原因になる。厄災はルーズな言語がルーズなプログラマに出会うときに起こる!

【参考】PC上でのプログラミング

コマンドプロンプト

Pythonは、WindowsデスクトップというGUI(グラフィカルユーザインタフェース)の世界ではなく、コマンドプロンプトというCUI(キャラクタユーザインタフェース)の世界で動作する。これはWindowsの前身である「MS-DOS」というCUIベースのOSの名残だが、実は現在のWindowsも基底レベルではここで動作している。いわばWindowsの奥の院である。図3-1は、最初に学んだプログラムを「hello.py」というファイルに保存し、コマンドプロンプトから実行した画面だ。

図3-1: コマンドプロンプトで実行する

みなさんが慣れ親しんだGUIの世界では、ウィンドウアイコン(正式にはピクトグラム)をキーボードやマウスで操作することで、さまざまな機能を呼び出す。これに対しCUIの世界では、ユーザがキーボードからコマンドラインを入力し、プログラムも実行結果を文字列形式で表示する。ユーザとコンピュータが文字でインタラクション(情報のやり取り)を行うこの画面をコンソールという。
 もちろんGUIプログラムの方が、画像やサウンドを駆使できるので見た目も華やかだが、それにはイベント駆動プログラミングオブジェクト指向プログラミングという中級レベルの知識が必須なので、まずはColabやコマンドプロンプトという、いわば「自動車教習所」でプログラミングの基本を身につけ、つぎの段階でTkinterやpygameなどのライブラリを使ったGUIプログラミングという「路上教習」につなげるのが、典型的な学習コースだ。CUIの世界は、なんだか見た目も黒くて暗いが、プログラムの動作は逆に見えやすく、理解しやすい。

コマンドプロンプトの世界では、こちらからコマンドラインを入力しなければ何も起こらない。なので、いくつかの覚えなくてはならないコマンドを図3-2に示す。これ以外にもたくさんあるが、Pythonプログラミングに必要なものに限っている。入力の手間を省ける便利な裏技も挙げておいた。

図3-2: コマンドプロンプトで用いるコマンドや裏技

つぎに、これから作るサンプルプログラムを置くためのディレクトリ※5を、USBメモリのルート直下に作ろう。ディレクトリ名は「python」がお奨め。コマンドプロンプト内の日本語入力はとても面倒だからだ。

5 Windowsの「フォルダ」を、コマンドプロンプトでは「ディレクトリ」と呼ぶ。

PCでのプログラミングを始める前に、スタートメニューからコマンドプロンプトを起動し、

f:(環境によって異なる。プログラムを置くドライブ文字)
cd python
という2つのコマンドを入力すれば準備完了だ。この手順に慣れておこう。

テキストエディタ

Pythonプログラムは、形式的には定型テキストファイルなので、作成にはテキストエディタを使う。具体的には秀丸エディタ推奨する。長年の実績をもつ、日本を代表するテキストエディタだし、Pythonの文法についても知っているため、ある程度の入力支援をしてくれる。からである。プログラミングにはメモ帳は向かない。
図3-3に、秀丸エディタでプログラム「hello.py」を入力した画面を示す。
最終行の[EOF]は、ファイルの終わりを示す表示であり、文字ではない(第1回の「ASCII文字コード」参照)。この記号を必ず、プログラムの最終行の次行に単独で置こう(つまり最終行は「改行」で終わる)。そうしないとPython処理系が最終行を実行しないこともあり、それに起因するバグはたいへん見つけにくい。

図3-3: テキストエディタでサンプルプログラムを入力する

プログラムを入力し、間違いがないか確かめたら、ファイルに「名前をつけて保存」する。図3-4に保存の際のダイアログ画面を示す。普通のテキストファイルと異なる点が2つあるので注意が必要だ。

図3-4: 「名前をつけて保存」する

pythonプログラムには、拡張子「.py」をつける※6
「ファイルの種類」「すべてのファイル(*.*)にして、「hello.py」のファイル名を入力し、「保存」ボタンを押す。「秀丸」をはじめテキストエディタでは、そのまま保存するとプレーンテキスト(*.txt)形式になるので、「ファイルの種類」を指定しないと、「hello.py.txt」というテキストファイルになってしまう。したがってPythonプログラムとは認識されない。ここは多くの初心者がつまづくところ。

6 GUI向けのPythonプログラムでは、「.pyw」という拡張子も使う。

エンコードの種類を、Unicode(UTF-8)とする
エンコードとは、システムでマルチバイト文字(日本語など)を扱う際の文字コードの種類をいう。テキストエディタでそのまま保存すると日本語(Shift-JIS)になるが、Python3.xでは、日本語を含むすべての文字をUnicode(UTF-8)で扱う規定なので、そう指定する※7。最初に指定すれば、後で上書き保存する際は気にしなくともよい。初心者は忘れがちなので、新たなプログラムの保存時には気をつけること。

7 PythonプログラムがUTF-8のテキストファイルであるということは、従来の多くの言語のプログラムが、ASCIIとShift-JISを併用しているのに対し、もう1バイト文字(英数字)と多バイト文字(日本語文字)を区別しなくてよいことを意味する。これはたいへん便利で、変数名や関数名を日本語で自由につけられる。この授業のサンプルプログラムでもしばしばその手を使っている。変な和製英語をつけるより、精神衛生上はるかによい。