1. プログラムの作成と実行、変数と型、代入と演算

全てのプログラム言語は、変数を使って演算(足し算、掛け算等)を行います。 変数には型(整数、実数、文字列)が必ずあります。変数に値を代入 した時点で変数の型は自動で決定されます。変数を定義して演算を行うことが 第1回講義の目的です。

  • プログラムを作成して実行できるようになる(コマンド操作とエラーを見て修正)。

  • 変数に値を代入する。

  • 型の概念を理解する。

  • 変数を使って演算する方法を理解する(演算子+,*,/,%,**等の使い方)。

  • 変数の値や型をターミナルに出力する方法を理解する(print文)。

注釈

プログラム言語を習得するコツは、プログラムを読んで中身を理解し実行する作業を繰り返すことです。プログラムを作成する際は、コピペしてかまいません。ただし内容を理解してコピペしてください。理解しないままコピペして例文を実行しても身につきません。コピペした内容を読んで少しずつ修正し、自分の考えた通りにプログラムが実行できるか確認しながら理解を深めます。

プログラムの作成と実行

Google colab にて各自のPCでプログラミングすることとします。Google colab を利用するために、Googleアカウントが必要になるので、準備しておいてください。以下、教育用端末のPyCharmを想定した説明になっていますが、Google colab 環境に読み替えてください。

プログラムの作成

PyCharm上でプログラムを保存するためのプロジェクトの中にディレクトリ(day01)を作成します。今後、講義毎にディレクトリを作成してその中にプログラムを作成すると良いでしょう。

コンピュータ処理/day01

作成したフォルダに以下のPythonファイルを作成します。

example-01.py

まずは画面に適当な文字を表示させるプログラムを作成します。今回は、何も考えずに画面に文字列を表示してみます。以下のプログラムを実行してみます。ブラウザ上でこのドキュメントを開いてコピペすれば良いでしょう。今後、コピペを頻繁に行うので以下のショートカットを覚えておいてください。

example-01
# ターミナルに「わたしは千葉大生です」を表示させるプログラム
print("わたしは千葉大生です")

操作

ショートカット

カット

Ctrlを押しながらx (Ctrl-x)

コピー

Ctrlを押しながらc (Ctrl-c)

ペースト

Ctrlを押しながらv (Ctrl-v)

コピペせずに入力する場合は、補完機能を積極的に使ってください。補完機能は[TAB]で使うことができます。例えば、[p]を押して[TAB]を叩くと、以下のようにpythonの予約語(Pythonの文法で特別な意味のある単語)でpから始まる候補のリストが表示されます。また[pri]まで入力して、[TAB]を叩くと[print]まで補完してくれます。[pri]からはじまるPythonの予約語は、printだけなので、[print]まで一気に入力を助けてくれます。

必須ではないですが、ブラインドタッチができると、素早くプログラムを完成させることができます。キーボードの[F]と[J]の位置に左手と右手の人差し指を置いて、画面を見ないで入力できるよう練習しましょう。キーボードの左下にあるCtrlキーは、左手の腹で抑えながら[x]や[v]を押してCtrl-xやCtrl-vを使います。下の写真を参照してください。

../_images/keyboard.png

実行は、Ctrl-[F5]を押すかマウスでメニューから再生ボタンを押してます。

プログラムの作成と実行は上の手順で行います。

example-01をもう少し解説します。

  • print() 文を使って文字列を表示する。

  • 表示させる文字列は、double quotation「 \" 」で囲む。

  • #の後ろの文字はコメントで何を書いても無視されます。空行も無視されます。

もう少し複雑なプログラムを実行してみましょう。 水素原子のd軌道をプロッ トしてみます。

example-02
import matplotlib.pyplot as plt
from scipy.special import sph_harm
from scipy.special import factorial
from scipy.special import assoc_laguerre
import numpy as np

a0 = 0.529177


def CalcFunc(n, l, m, r, theta, phi):
    rho = 2 * r / a0
    coef1 = np.sqrt((2 / (n * a0))**3 * factorial(n - l - 1) /
                    (2 * n * factorial(n + l)))
    coef2 = np.exp(-rho / 2) * rho**l
    # ラゲール(Laguerre)
    L = assoc_laguerre(rho, n - l - 1, 2 * l + 1)
    # 球面調和関数(spherical harmonic function)
    if m == 0:
        Y = sph_harm(m, l, phi, theta)
    if m > 0:
        Ya = sph_harm(-m, l, phi, theta)
        Yb = sph_harm(m, l, phi, theta)
        Y = 1/np.sqrt(2) * (Ya + (-1)**m*Yb)
    if m < 0:
        Ym = sph_harm(m, l, phi, theta)
        Yb = sph_harm(-m, l, phi, theta)
        Y = 1j/np.sqrt(2) * (Ym - (-1)**m*Yb)
    psi = coef1 * coef2 * L * Y
    psi2 = psi.real * np.conj(psi.real)
    return psi2


# 主量子数, 方位量子数, 磁気量子数
pnt, spnt, Llim = 51, 25, 3
n, l, m = 3, 2, 2
Ldata = np.linspace(-Llim, Llim, pnt)
x, y, z = np.meshgrid(Ldata, Ldata, Ldata)
r = np.sqrt(x**2 + y**2 + z**2)
idx = r != 0
theta = np.zeros((pnt, pnt, pnt))
theta[idx] = np.arccos(z[idx] / r[idx])
phi = np.arctan2(y, x)
psi2 = CalcFunc(n, l, m, r, theta, phi)

fig, ax = plt.subplots()
ax.contour(x[:, :, spnt], y[:, :, spnt], psi2[:, :, spnt])
ax.set_xlim(-Llim, Llim)
ax.set_ylim(-Llim, Llim)
x0, x1 = ax.get_xlim()
y0, y1 = ax.get_ylim()
ax.set_aspect((x1 - x0) / (y1 - y0))
ax.set_xlabel('x/angstrom')
ax.set_ylabel('y/angstrom')
ax.set_title('d-orbital (n, l, m) = ({}, {}, {})'.format(n, l, m))
fig.savefig('d-orbital.png')
plt.show()

プログラムを実行すると、z=0、xy平面の確率密度(dxy)を等高線(コンターマップ)でプロットした図が表示されます。

../_images/d-orbital.png

このように簡単な文字出力から複雑な計算とプロットまで、カバーしているところがpythonの魅力です。

プログラムのデバック

プログラムの間違いを探して修正する作業をデバックと呼びます。文法に間違 いがあると、プログラムはエラーを表示して停止します。ためしに以下の プログラムを実行してみます。

example-03
1print("私の一番好きな元素は")
2print("ウランです。")
3printe("私の一番嫌いな元素は")
4print("Fです。")

このプログラムを実行すると以下のようなエラーになります。

1私の一番好きな元素は
2ウランです。
3Traceback (most recent call last):
4  File "hoge.py", line 3, in <module>
5    printe("私の一番嫌いな元素は")
6NameError: name 'printe' is not defined

2行目まで問題なく実行されていますが、3行目で print と書くところを printe と書いています。デバックする時は、エラーの内容をよく読むことが修正への近道です。エラー内容から3行目が間違っていることを教えてくれています。作成したプログラムがエラーとなったら、エラーの内容をよく読んで間違いを修正します。

プログラムの基本事項

プログラムは、テキストファイルで作成します。テキストファイルの上から順 番に実行されます。今後、文法の詳しい説明を行いますが、インデント(字下 げ)は特別な意味を持ちます。pythonは、プログラムの行頭にインデントを使っ て、プログラムの流れを制御するので、行頭に無駄なスペースを入れないこと に注意してください。また、上の例で示しているように文頭の#はコメント文 となり、コメント文としてスキップされます。コメント文には変数の意味や処理の内容を好きなように記述できます。

注釈

冗長になるくらいコメント文をプログラムに書いておくことは重要です。自分で作成したプログラムでも2週間後には、ほぼ内容を忘れて(別人化)しまっています。少しうるさいくらいまで、コメント文にプログラムの変数の説明や解説を入れておくと、2週間後の自分や他人がプログラムを容易に理解できます。

変数の利用

数字や文字等をコンピュータに記憶させる文字を 変数 と呼びます。 変数sを使ってexample-01を書き直してみます。

example-04
1s = "私は千葉大生です。"
2print(s)

変数に何かを代入する場合は、 = で代入する値を指定します。01-example04の場合、sという変数に"私は千葉大生です。"が代入されています。変数として利用できる記号は以下のとおりです。大文字と小文字は区別されます。変数はスペースを含むことができないので、スペースを使いたい場合は、アンダースコア(_)を使います。

  • 小文字の英字

  • 大文字の英字

  • 数字

  • アンダースコア

注意点として、数字は変数の先頭に使うことができません。以下の変数はpythonで使える文字です。

hoge hoge_ hoge3 HOGE A_is_B

以下の変数はpythonで使えない(エラーになる)文字です。

4hoge "hoge (hoge3 .HOGE

変数として使えない文字列を使おうとしたら、IDLE上でhighlightされる(色が 変わる)ので、間違いに気がつくかと思います。

変数の型と代入

変数に代入でいる値は、数字や文字列です。変数に値が代入されると、変数の 型(type) が決まります。変数は、必ず何かしらの型を持っています。どの ようなプログラミング言語でも変数は型をもっていて、プログラムを書く人は、 型を意識すること必要です。Pythonで用いる主な型は以下のとおりです。

型の名

値の例

整数型(int)

1 2 3 9 -10 -56等の小数点をもたない整数

浮動小数点型(float)

1.1 54.3 0.2 -0.3, 3.00e8 等の小数点を持つ数字

文字型(str)

hoge 千葉大 等の文字列

変数を「=」で結べば、値を代入できます。プログラムの作成者は、定義した 変数が何の型になっているか、常に意識することが重要です。変数の型を明示する こともできますが、変数に値を代入すると値によってPythonが変数の型を自動決めてくれます。

注釈

C言語等のコンパイル言語は、変数の型をあらかじめ宣言する必要があります。Python等のスクリプト言語は、変数へ値を代入すると同時に型が決まってしまうため、変数の型を宣言する必要はありません。ただし、変数の型を指定した処理がたくさんあるので、プログラム作成者は変数の型を常に意識する必要があります。

また type() を使うことで変数の型を取得できるのでいくつか試してみます。

example-05
 1# 変数の代入と表示
 2a = 1                         # aに1を代入 型はint
 3print("type of a:", type(a))  # aの型を表示
 4a = 1.0                       # aに1.0を代入 型はfloat
 5print("type of a:", type(a))  # aの型を表示
 6a = 3.0e8                     # aに300000000
 7print("type of a:", type(a))  # aの型を表示
 8a = "hoge"                    # aに"hoge"を代入 型はstr
 9print("type of a:", type(a))  # aの型を表示
10a = "3"                       # aに"3"を代入 型はstr intでないことに注意
11print("type of a:", type(a))  # aの型を表示
12a, b = 3, -4.2                 # 2つの変数を同時に代入している。
13print("type of (a, b):", type(a), type(b))
14a, b = 3, "3"
15print("type of (a, b):", type(a), type(b))  # aはint, bはstr

変数の代入は1文で2つの変数に代入したり、2つの変数に同じ値を代入する次のような書式でも可能です。

example-06
1a, b = 2.3, "3.2"      # aに2.3, bに"3.2"を代入
2a = b = 3              # aとb両方に3を代入

注釈

type()やprint()は()に引数を与えて引数を表示させるpythonの標準関数です。関数の定義や使い方は、 ../03_関数とメソッド/03 で扱いますが、print()文の引数に変数を与えれば画面に出力、type()の引数に変数を与えれば引数を型を取得できると知っておけば良いでしょう。

整数(int)変数の定義

値が整数の場合、変数はint型にセットされます。

example-07
1H = 1                      # Hの原子番号の定義
2O = 8                      # Oの原子番号の定義

浮動小数(float)型変数の定義

値が浮動少数の場合はfloatにセットされます。float型は指数表現を使うことができます。「3e5」とは「3×10の5乗」のことであり「300000」と同じ値です。また「7.1e-4」とは「7.1×10の-4乗」のことで「0.00071」と同じ値です。値を "" で囲んだ場合は、str型になります。下例のように、整数値として 3 を代入する場合と "3" を代入する場合では、型が異なることに注意してください。

example-08
1s = "3"                    # sは文字列
2i = 3                      # iは整数型
3c = 300000000.0            # float型で光の速度の定義
4NA = 6.0221367e23          # float型でアボガドロ数の定義

文字(str)型変数の定義

文字列を " で囲むことで文字列型の変数を定義できます。改行コード(\n)や " そのものを変数として定義したい場合は、 ' (single quotation) や \ (日本語キーボードの場合¥マーク)により文字をエスケープします。また改行も含めて文字を定義したい場合、 """ (double quotation3つ)を使います。例をみてみましょう。

example-09
 1moji = "千葉"                         # ""で文字列の定義
 2print(moji)
 3
 4moji = "千葉は日本です。\
 5日本はアジアです。"                   # 改行コードをエスケープしているのでエラーにならない。
 6print(moji)
 7
 8moji = "千葉は日本です\\。"           # \を表示させるために、\を\でエスケープ
 9print(moji)
10
11moji = "\"千葉\""                     # \で"をエスケープ(文字として扱う)
12print(moji)
13
14moji = '"千葉"'                       # ''で""を含む文字列の定義
15print(moji)
16
17moji = """私は千葉大生です。
18勉強大好きです。
19"""                                   # 改行コードも文字として定義できる
20print(moji)

変数を使った演算

数学でおなじみの足し算、引き算、割り算、掛算は、演算子(*, +, -, /, **等)を 使ってできます。演算の優先順位のために()も使えます。intとfloat型の変数 に対して使える演算子は以下のとおりです。

演算子

意味

*

a * b

aとbの掛け算を行う。a×b

/

a / b

aとbの割り算を行う。a/b

+

a + b

aとbの足し算を行う。a+b

-

a - b

aとbの引き算を行う。a-b

**

a ** b

aのb乗を計算する。ab

%

a % b

aをbで割った余りを求める。 7 % 4 は3

//

a // b

切り捨て除算を求める。 7 // 2 は3

文字型の変数は、以下の演算子使って演算を行うことがでます。ただし、文字型に許される演算は、「+」と「*」の2つだけです。

演算子

意味

+

a + b

文字列aと文字列bを連結する。"ab" + "cd" = "abcd"

*

a * b

文字列aをn回繰り返します(nはint型)。4 * "cd" = "cdcdcdcd"

複数の演算子を作用させる場合は、優先順位があります。演算子の優先順位は以下のとおりです。

1つの式での演算子の優先順位(高い順番)

**

* / % //

+ -

例えば \(3 + 4 \times 8\) を計算する場合、以下のように書けば \(4 \times 8\) が優先されます。

example-10
1a = 3 + 4 * 8    # 4×8を先に演算して3を足す
2print(a)         # aは35

また、数式と同様に括弧を使えば演算が優先されます。

example-11
1a = (3 + 4) * 8  # 3+4を演算して8をかける
2print(a)         # aは56

文字型変数対して、文字列同士の+ と整数との掛け算以外の演算はエラーになります。

example-12
1a = "千葉"
2b = "大学生"
3print(a + b)           # 千葉大学生の表示
4print(3 * a)           # 千葉千葉千葉の表示
5print(4.0 * a)         # これはエラー

いくつか演算の例を以下にあげます。演算によって生じる結果も特定の型をもちます。同じ型同士の演算は、同じ型の結果を返します。int型とfloat型の演算(+ - / * ** )は、float型になります。

example-13
1a, b = 3, 7                # aとbはint
2c = a / b
3print("a/b:", type(c))     # int型とint型の割り算はfloat型
4c = a * b
5print("a*b:", type(c))     # int型とint型の掛け算はint型
6
7a, b = 3.2, 7              # aはfloat型、bはint型
8c = a * b
9print("a*b:", type(c))     # aとbの掛け算はfloat型

変数aに、変数aを使った演算を行うことで変数aの内容を変更できます。以下の例をみてください。

example-14
1a = 3.0     # 変数aの定義
2a = a + 1   # 変数aは、4(3.0 + 1 = 4)が代入される
3a = a - 3   # 変数aは、1(4.0 - 3 = 1)が代入される
4a = a * 4   # 変数aは、4 (1 * 4 = 4)が代入される
5a = a / 2   # 変数aは、2 (4 / 2 = 2)が代入される

a = a + 1 のような変数aの値をupdateする演算は、プログラムの中で頻繁に使いま す。次のような単項演算子で短く書き直すこともできます。

example-15
1a = 3.0    # 変数aの定義
2a += 1     # a = a + 1と同じ意味
3a -= 3     # a = a - 3と同じ意味
4a *= 4     # a = a * 4と同じ意味
5a /= 2     # a = a / 2と同じ意味

変数を使ったいくつか計算をしてみます。「三平方の定理」を使って辺の長さを計算してみます。直角を含む三角形の直角をなす辺の長さを \(a, b\) 、残りの辺の長さを \(c\) とした場合、以下の関係があります。

\[ \begin{align}\begin{aligned}c^2 &= a^2 + b^2\\c &= \sqrt{a^2 + b^2}\end{aligned}\end{align} \]

変数として \(a\)\(b\) を与えて \(c\) を計算するプログラムは以下のとおりになります。

example-16
1a = 10   # aの長さ
2b = 3    # bの長さ
3c = (10**2 + 1**2)**(0.5) # cの計算
4print("c =", c) # cの表示

もう少し複雑な計算を行ってみます。 \(a, b, c\) を与えて \(\alpha\) を計算してみます。 \(a=3.0, b=2.3, c=-12.3\) とします。

\[\alpha = \frac{ a+b }{a\cdot c \cdot (b+c)^3} + (a + b)^{\frac{1}{3}}\cdot (b + c^2)^3\]
example-17
1a, b, c = 3.0, 2.3, 12.3   # a, b, cの定義
2alpha = (a + b) / (b + c)**3 /a /c + (a + b)**(1 / 3) * (b + c**2)**3  # 分母を括弧でくくる
3print("alpha = ", alpha)

結果として \(\alpha\) は6317047.042422106と求まります。

次のように分母と分子を括弧でくくったり、別々に書いても結果は同じです。 長い数式は、わかりやすく分割したり括弧を使って書く方が良いでしょう。

example-18
1a, b, c = 3.0, 2.3, 12.3   # a, b, cの定義
2# 分子と分母、項1と項2を別々に計算する
3bunshi = a + b
4bunbo = a * c * (b + c)**3
5term1 = bunshi / bunbo
6term2 = (a + b)**(1 / 3) * (b + c**2)**3
7alpha = term1 + term2
8print("alpha = ", alpha)

当然ですが、同じ結果が得られます。

クイズ

Q1

次の変数a, b, c, d, eの型を表示しなさい。

1a = "3.0"
2b = 300000
3c = 20000
4d = b/c
5e = c * 1e-10

答え

 1a = "3.0"
 2b = 300000
 3c = 20000
 4d = b/c
 5e = c * 1e-10
 6print(a, type(a))
 7print(b, type(b))
 8print(c, type(c))
 9print(d, type(d))
10print(e, type(e))

Q2

変数x=0.3, y=2000000000, z=0.00000003を定義して、Aを以下の式を使って計算しなさい。

\[A = \frac{x^2y^{\frac{1}{3}}}{(x + y + z)\cdot x}\]

答え

1x, y, z = 0.3, 2e9, 3e-8
2A = x**2 * y**(1/3)/(x + y + z)/x
3print(A)

問題3

以下のプログラムで定義されている変数aとbの演算より、文字列「千葉千葉千葉大学千葉千葉千葉大学」を作成して表示する。なお、単項演算子( += )を使ってください。

a = "千葉"
b = "大学"

答え

1a, b = "千葉", "大学"
2s = 3 * a
3s += b
4s += 3 * a
5s += b
6print(s)

Q4

圧力, 体積, 温度(\(P, V, T\))が与えられた時、 理想気体の状態方程 式を使って、モル数 \(n\) を計算するプログラムを作成する。圧力, 体積, 温度 \(P, V, T\) とガス定数 \(R\) は以下のように与える。

\[\begin{split}P &= 2.5\times 10^5\ {\rm Pa}\\ V &= 1.2\ {\rm m}^3\\ T &= 30 ℃\\ R &= 8.31451\ {\rm J/K\cdot mol}\end{split}\]

答え

1P = 2.5e5   # 圧力, Pa
2V = 1.2     # 体積, m3
3T = 30      # 温度, K
4R = 8.31451 # ガス定数
5T = T + 273.15  # degC -> Kelvin
6
7# PV=nRTよりn=PV/RT
8n = P * V/(R * T)
9print(n)

Q5

水分子1,000個が立方体の中に存在する。水の密度を \(\rho=1.0\ {\rm g/cm^3}\) とした場合、立方体の1辺の長さを計算して Å(= \(10^{-10}\ {\rm m}\)) で求める。なお水の分子量と アボガドロ数は、以下の数字を使う。

水の分子量 \(M_w\)

\(18.015280\ {\rm g/mol}\)

アボガドロ数 \(N_A\)

\(6.0221367 \times 10^{23}\ {\rm mol^{-1}}\)

答え

 1NA = 6.0221367e23    # アボガドロ数 個/mol
 2Mw = 18.015280       # 水の分子量 g/mol
 3
 4W = 1000 / NA * Mw   # weight, g
 5rho = 1.0 * 1e-24    # g/cm3 -> g/Å3
 6
 7# rho = W/Vより V = W/rho
 8V = W/rho            # 体積, Å3
 9L = V**(1/3)         # 立方体の長さ, Å
10
11# 出力
12print("立方体の1辺の長さ", L, "Å")

Q6

変数sとtに文字「千葉」と「東京」をそれぞれ定義する。 空文字の変数k (k="")も定義する。 変数kをupdateし(演算子 +=等を使って)次の文字を表示させなさい。

千葉東京千葉千葉千葉東京

ちなみに以下のような解答はダメです。 +=を使って変数sをupdateするプログ ラムを作ってください。

s, t = "千葉", "東京"
print(s + t + s + s + s + t)

答え

k, s, t = "", "千葉", "東京"
k += s
k += t
k += s
k += s
k += s
k += t
print(k)