2. Pythonの基本

まずはPythonプログラムの実行方法と基本的な言語仕様を抑えよう.ただし,ここではCまたはFortranの基本的な文法は既に知っているものとして,それらと比較をしながら基本的な事項を抑えるにとどめる.ここで解説する以上の事柄については必要に応じて調べて欲しい.

参考

2.1. プログラムの実行

お決まりの"Hello, World !"を標準出力に表示するサンプルプログラム( hello.py )は以下の通りである.単純に print 関数に表示したい文字列を渡せばよい [1]

1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4print('Hello, World !')

これを実行するにはコマンドラインで

1$ python hello.py

または

1$ ./hello.py

とすればよい.2番目の実行方法は hello.py が実行権限を持っていなければならない [2]. 実行権限を与えるには例えば

1$ chmod 755 hello.py

とすればよい.

ここでCやFortranでは必須であったコンパイル作業が必要なかったことに注意しよう.Pythonはこれらのコンパイル型言語とは異なりインタープリター型の言語に分類される.すなわち,コンパイルによって全てが一旦機械語に変換されてから実行されるのではなく,プログラムの実行時に一文ずつ読み込まれて,解釈され(interpret),実行される.したがって,一般にインタープリター型言語の実行速度はコンパイル型言語に比べて非常に遅い.Pythonにおいてもこれは正しいが,この問題は多くの場合(少なくともある程度は)回避することが可能である.その代わりに変数の型宣言などを事前にすることなく使うことができたりと,比較的お手軽に使えるのが大きな利点である.このようにソースコードを(コンパイルすることなく)そのまま実行する言語をスクリプト言語と呼んだりもする.bashなどのシェルも一種のスクリプト言語である.

また,Pythonはインタープリターとしての特徴を生かして対話的な使い方も可能である.これについては 対話型の実行方法 で別途紹介するが,ここではまずはコマンドラインでの実行方法に慣れておこう [3]

2.2. ソースコードの基本構造

Pythonのプログラムは(変数,関数,クラスなどの定義を除けば)基本的には上から順に実行されると思ってよい.ただし各行の # 以降はコメントと解釈され無視される.また,Fortranとは異なりアルファベットの大文字と小文字は区別される.

Pythonの大きな特徴は 構文ブロックがインデント(字下げ)で区別される という点である.まずは以下のサンプルを見てみよう.

 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4# これはコメント行
 5if 1:
 6    # pythonでは構文ブロックは全てインデント(字下げ)によって区切られる
 7    print('Hello')
 8    print('This will be printed out')
 9else:
10    # ここには到達しない
11    print('This will be ignored')
12
13
14# ここでは sys という名前のモジュールを import する
15# プログラムを実行途中で終了するには sys.exit を呼ぶ
16# sys.exitに与える整数は終了コード(通常は0が正常終了でそれ以外は異常終了)
17import sys
18
19if 1:
20    sys.exit(0)
21else:
22    sys.exit(-1)

5-11行目が if-else による分岐である.これについては後述するが,その意味は明らかであろう.同じような分岐はCでは

1if ( 1 ) {
2  printf("Hello");
3  printf("This will be printed out");
4else {
5  printf("This will be ignored");
6}

Fortranでは

1if ( .true. ) then
2  print *, 'Hello'
3  print *, 'This will be printed out'
4else
5  print *, 'This will be ignored'
6end if

のように記述することになる.多くの言語では何らかのキーワードや記号(Fortranならば ifend if など,Cならば {})を用いて制御構造の区切りを表しているのに対して,Pythonではインデントで区切りを付けることになっている.したがって,例えば次のような書き方はエラーとなる.

1if 1:
2    print('Hello')
3  print('error !')  # インデントがあっていない
4print('error !')    # 次に続くelseと整合しない
5else:
6    print('This will be ignored')

すなわち, 文頭に余計なスペースなどがあるソースコードは文法的に許されない のである.多くの言語ではあくまで人間の見やすさのためにインデントをしているのであって,文法的には必須ではない.したがって,書き手に依存して簡単に読みにくいコードが出来てしまう.Pythonではインデントを文法として強制することで,誰が書いても読みやすいコードになるのである [4]

なお,このようなインデントを手動で行なうのはあまり賢いやり方ではないので,エディタの機能をうまく使うとよい.最近の高機能なエディタであればどれでもPythonを扱うための便利な機能を提供している.

また,Pythonには標準で様々なモジュール(ライブラリ)が用意されており,それらを組み合わせてプログラムを開発していくことになる.モジュールの使い方についての詳細な説明はここでは割愛するが,モジュールを使うにはまず import する必要がある.これはFortranの use と同じものだと考えて良い.Cでは include に近い [5]

上の例では17行目で sys という名前のモジュールを import し,20行目,22行目で sys.exit() を呼んでいる.Pythonのプログラムは基本的には上から順に実行され最後の行に達した段階で終了するが,何らかのエラーが発生した場合など,途中でプログラムの実行を打ち切りたい場合には sys.exit() を呼べばよい.(Fortranの stop ,Cの exit() 関数と同じものである.)

2.3. 変数

スクリプト言語であるPythonにおける変数の扱いはコンパイル型言語とは大きく異なり,変数を使う際に型宣言をする必要がない.例えば以下のように変数を使うことができる.

4n = 10           # nは整数 (4byte = 32bit)
5x = 3.14         # xは実数 (8byte = 64bit)
6
7print('n = ', n)
8print('x = ', x)

ここで変数 nx の型を指定していないことに注意しよう.Pythonでは明示的にデータ型を指定しなくても, = で数値を代入する際に(実行時に)右辺値に応じて自動的に変数の型が選択されることになっている.したがって n は整数, x は実数となる.なお,Python3では実数型(浮動小数点数)はデフォルトで8byte(Cの double ,Fortranの double precision または real(8))となる.一方で,整数型には決まったサイズは存在しない(値が大きくなると,必要に応じてサイズが大きくなる).

CやFortranではプログラムや関数・サブルーチンの先頭で変数を宣言してから使う必要があったのに対して,いつでも好きなときに変数を定義して使うことができるので大変便利である.しかし,まだ定義していない変数を参照するとエラーが発生する.例えば先ほどの例の後に

1print('y = ', y)

としても,変数 y が定義されていないので実行時にエラーが発生する.例えば sample2.py の10行目のコメントアウトを外して実行すると,

1Traceback (most recent call last):
2  File "sample/chap02/sample2.py", line 10, in <module>
3    print('y = ', y)
4NameError: name 'y' is not defined

のように表示されてしまう.これは意外とよくある間違いなので気をつけよう.

なお,Pythonではプログラム中で書き換えのできない定数(Cの const, Fortranの parameter)は言語仕様としては提供されていない.ただし,必要な場合には実質的には定数と振る舞うような変数を用いることは可能である.

2.4. 算術演算

数学的な演算はCやFortranと共通の点が多いが,多少注意が必要である.以下に算術演算の使用例を示す.

 5print(12 + 5)  # 和 => 17
 6print(12 - 5)  # 差 => 7
 7print(12 * 5)  # 積 => 60
 8print(12 // 5) # 商 => 2
 9print(12 % 5)  # 余り => 2
10print(12 / 5)  # 実数としての割り算 => 2.4
11print(2**3)    # べき乗 => 8

CやFortranでは整数同士で割り算( / 演算子)をすると返値も整数となるため,上の例で言えば 12 / 52 となるが,Pythonでは自動的に実数同士の割り算に変換される.代わりに // を整数同士の割り算をする演算子として用いる.

また % 演算子はCと同様に整数同士の割り算の余りを返す.Fortranでは mod 関数に相当する.逆に ** 演算子はFortranと同じべき乗を返すが,Cでは pow 関数に相当する.

2.5. 数学関数

数学関数を使うには math というモジュールを import すればよい.

1import math

その上で,例えば \(\exp(x)\) を計算するには

1math.exp(0.5)

のように関数 math.exp を用いればよい.それ以外にもCやFortranに組み込みで用意されているような数学関数はPythonにも用意されていると考えてよいだろう.

注釈

ここではPython本体に組み込みのモジュールという意味で math を紹介した.しかし,科学技術計算でPythonを使う場合にはほぼ間違いなく numpy というモジュールがインストールされている環境を使うことになるので,その場合には numpy に含まれている数学関数を用いる方が何かと便利である.とりあえずは全く同じ使い方であると考えておいて構わない.

2.6. キーボード入力

ここでコマンドラインでPythonプログラムを実行する際にキーボードからの入力を受け取る方法を一つ紹介しておこう.これには組み込み関数の input を使う.

4# キーボード入力を読み込む
5s = input('Input something: ')
6print('Your input is : ', s)

input によってキーボード入力は文字列として読み込まれるので,整数や実数として用いたい場合には文字列から型を変換する関数 int もしくは float を用いる必要がある.変換された後は以下の例のように通常の整数,実数の変数として扱えば良い.

 8# 整数に変換
 9a = int(input('Input integer 1: '))
10b = int(input('Input integer 2: '))
11print('Sum of two integers : ', a + b)
12
13# 実数に変換
14c = float(input('Input real: '))
15print('Square of float : ', c*c)

プログラムに入力を与える方法は他にも色々と考えられるが,まずはこの一番簡単な方法を使うことにしよう.

2.7. 文字列フォーマット

Pythonの文字列のフォーマットの仕方について簡単に触れておこう.ここではよく使われるprintf形式と format() の使い方について最低限の情報を述べるにとどめる.printf形式はC言語とほぼ同じで,また古いPythonでも使えたことから慣れている人(筆者のことである)が好んで使う傾向がある. format() はprintf形式の問題を解決するために導入されたという経緯があるので,今から覚えるのであればこちらの方がよいであろう.いずれにせよ,一気に全て覚えるようなものではなく,必要に応じてPythonの公式ドキュメント等を参照して少しずつ慣れていけば十分である.

2.7.1. printf形式

C言語のprintfで用いられるのとほぼ同じ要領で文字列のフォーマットができる.これには % を用いて,例えば以下のように用いる.

7s = '%s is more powerful than %s' % ('Python', 'Fortran')
8print(s)

ここで7行目の文字列中の %s はフォーマットを指定子の一種で,ここでは与えられた変数を文字列としてフォーマットすることを指定している.ここでは与えられた 'Python' および 'Fortran' をそれぞれ文字列としてフォーマットし,フォーマットされた結果の文字列を変数 s に代入している.

C言語を知っている人はC言語のprintfと基本的に同じフォーマット指定子が使えると考えてよい.例えば以下のように用いることができる.

10i = 2021
11a = 3.1415
12b = 2.7182
13print("i  = %-5d" % (i))
14print("pi = %4.2f" % (a))
15print("e  = %5.3f" % (b))

フォーマット指定子の詳細については 公式ドキュメント を参照のこと.なお, % に続く ()tupleオブジェクト である.ここに dictオブジェクト を与えることも可能であるがここでは省略する.

2.7.2. format()

Pythonの文字列は format() というメソッド [6] を持ち,これを用いることで文字列のフォーマットができる.以下に例を見てみよう.

21s = "{} is more powerful than {}".format('Python', 'Fortran')
22print(s)

のように {} が埋め込まれた文字列の format() メソッドに渡した値が順に {} にフォーマットされる.デフォルトでは {} の出現順と format() の引数の位置(順番)が対応しているので,この例では"Python is more powerful than Fortran"が出力される.

実際には {} には引数の位置を指定することができる.以下の例ではこれを陽に指定したもので,この結果"Fortran is more powerful than Python"が出力されることになる.

25s = "{1} is more powerful than {0}".format('Python', 'Fortran')
26print(s)

引数位置に加えて, {引数の位置:フォーマット} のような形で出力のフォーマットを指定することもできる指定の仕方はprintf形式に似ているが,細かいところが少し違っている.以下の例はprintf形式の例と全く同じフォーマットで値を出力している.

28print("i  = {:-5d}".format(i))
29print("pi = {:4.2f}".format(a))
30print("e  = {:5.3f}".format(b))

なお,ここで「引数の位置」は省略されていることに注意して欲しい.

また {} に与える引数指定には,引数の順番だけでなく format() メソッドに与えられた引数名( キーワード引数 参照)で指定することも可能である.詳細なフォーマット指定の方法とあわせて 公式ドキュメント を参照して欲しい.

2.8. 第2章 演習課題

2.8.1. 課題1

サンプルを実行して動作を確認しよう.

2.8.2. 課題2

標準出力に Hello, Python ! 出力するプログラムを作成しよう.

2.8.3. 課題3

標準入力から三角形の底辺 \(l\) と高さ \(h\) を読み込み,三角形の面積を表示するプログラムを作成しよう.

1$ python kadai3.py
2Input l : 5.0       # キーボード入力
3Input h : 3.0       # キーボード入力
4Area of triangle :  7.5

2.8.4. 課題4

キーボード入力で与えられた実数 \(x\) について,テイラー展開の公式

\[\sin x = x - \frac{x^3}{3 !} + \frac{x^5}{5 !} - \frac{x^7}{7 !} \cdots\]

を適当な次数(例えば2次とか3次)で打ち切りることで \(\sin x\) の近似値を求め,組み込み関数 sin(x) で求めた値と比較するプログラムを作成しよう.例えば \(x = 0.01,0.1,0.2\) などについて,実行して結果を確かめること.

例えば以下のような結果が得られればよい

1$ python kadai4.py
2Input x : 0.2                     # キーボード入力
31st order =  0.2
43rd order =  0.19866666666666669
55th order =  0.19866933333333336
67th order =  0.19866933079365082
7exact     =  0.19866933079506122