第3回 Pythonの基礎1#


Open In Colab


この授業で学ぶこと#

この授業では、数値や文字列といった基本的なデータの扱い方を学ぶ。

今の段階では細かいところはわからなくても、なんとなくPythonを実行できれば十分である。プログラミングは手で覚えるところがあるので、簡単な例も逐一タイピングして、実際に動かしながら学んでほしい。

最初のプログラム#

まずはPythonプログラムを動かしてみよう。

print("Hello, world!")
Hello, world!

ノートブックの文字を入力できる部分をセルという。 セルに見本通りに文字を入力して、左の実行ボタンを押すと Hello, world! と表示されるはずだ。 この Hello, world! と表示させるプログラムは、どのプログラミング言語でも最初の一歩として紹介されることが多い。

前回の復習になるが、このようなコンピューターに対する命令のことをプログラムといい、それをPythonなどの言語で記述したものをソースコード (またはコード)という。 また、左の実行ボタンを押す以外の実行方法として、キーボードで Shift を押しながら Enter と入力する方法がある。便利なので覚えておこう。

半角と全角

上のコードを入力する際に、全角文字を使うとその場所によってはエラーになる。あとで説明するように日本語の文字列データを扱うときや、コメントを書くとき以外は、全角文字を使うことはほぼない。常に半角文字になっているか気をつけながら入力する習慣をつけよう。

四則演算#

次に、簡単な数式を計算させてみよう。電卓にやらせていたような計算も、Pythonで行った方がずっと便利なことが多い。

主な記号(算術演算子という)を次にまとめる。

算術演算子

意味

+

足し算

-

引き算

*

かけ算

/

割り算

//

割り算(小数を切り捨て)

%

割り算の余り

**

累乗

足し算 +、引き算 - および割り算 / については馴染みのある記号だろう。 かけ算は × ではなく * という記号を用いる。

// および % は、小数の出てこない余りつき割り算を行うのに用いられる。例えば5割る3の答えは、商が1余りが2となるが、商は 5//3、余りは 5%3 によって求めることができる。

累乗は ** で表される。例えば3の5乗(つまり 3*3*3*3*3)は、3**5 で求めることができる。

以下のコードを、結果を予想しながら実行してみよう。なお、ノートブック環境では print() と書かなくても、セルの最終行を評価した値が自動的に表示される。

-2 + 2
0
-2 * 2
-4
7 / 2
3.5
7 // 2
3
7 % 2
1
2 ** 5
32

日常の生活でもちょっとした計算をする際に、Pythonをパッと起動して使えると便利である。例えば、家庭教師をしていて遭遇しそうな問題を次に並べてみたが、Pythonを使えば答えを簡単に確かめることができる。

練習1

(1) 80円のりんごを6個、120円のオレンジを9個買った。合計はいくらか。
(2) りんごは5%の値引きがあったとする。このとき合計はいくらになるか。

80 * 6 + 120 * 9
80 * 0.95 * 6 + 120 * 9

練習2

(1) 365を12で割った商と余りを求めよ。
(2) 2023の2023乗の1の位の数字は何か。 ヒント: 1の位の数字は10で割った余りである。

print(365 // 12)  # 商
print(365 % 12) # 余り
2023**2023 % 10

練習3

(1) 10万円を年利率5%で運用したとき、10年後の金額を求めよ。また20年後にはいくらになるか。
(2) 3の平方根の値を小数で求めよ。 ヒント: 平方根は0.5乗で計算できる。

print(10 * (1.05**10))
print(10 * (1.05**20))
3**0.5

計算の順番#

次のコードの実行結果を予想してみよう。

2 + 3 ** 2 / 4 * 2 ** 2 - 5
6.0

予想は当たっただろうか。ここでは計算の順番に関するルールを学ぶ。

まず、演算子には優先順位があり、累乗 **、掛け算・割り算 *, /, //, %、足し算・引き算 +, - の順に優先される。また、同じ優先順位の演算子は、前から順に実行される。ただし、普通の数学と同じく () を付ければ、その中身の計算が最優先される。

このルールにしたがうと、上の数式は次のように計算される。
まず、足し算・引き算より掛け算・割り算・累乗が優先されるので、真ん中の項が先に計算される。() を使って明示的に書けば、次の式と同じということである。

2 + (3 ** 2 / 4 * 2 ** 2) - 5
6.0

さらに、真ん中の項のうち累乗が優先されるので、次のように 3**22**2 が先に計算される。

2 + ((3 ** 2) / 4 * (2 ** 2)) - 5
6.0

累乗を計算したあとの 9 / 4 * 4 は前から順に計算されるので 9 / 4 * 4 = 2.25 * 4 = 9となる。したがって、最終的な答えは 2 + 9 - 5 = 6 となる。

ところで、最初の式はとてもわかりづらいと感じなかっただろうか。 これは長年プログラミングに触れている人にとっても同じであり、最後の()を活用した式の方が見やすい。 間違いを減らすためにも()を活用しながら、わかりやすい記述を心がけよう。 さらにコメントすれば 9 / 4 * 4 より 9 * 4 / 4 の順番の方が、計算の順番に安心感がある。 したがって、最初の式は次のように書くとより良い。

2 + ((3 ** 2) * (2 ** 2) / 4) - 5
6.0

変数#

ここでは、数値などのデータに名前をつける方法について学ぶ。

先ほどの練習1の答えはそれぞれ次のとおりであった。

80 * 6 + 120 * 9
1560
80 * 0.95 * 6 + 120 * 9
1536.0

こういう式を書くとき、数値と演算子のみで書くと、目で見て意味がとりづらくなる。 また繰り返し現れる数値があるが、それぞれ2回タイピングするのは間違いのもとである。

そんなときは数値に名前をつけると便利である。Pythonでは次のような形式でデータに名前をつけることができる。

名前 = 式

左辺の名前のことを変数という。右辺はあえてデータではなく式と表現した。式の場合はそれを評価した結果の値に名前がつく。 このことを変数に値を代入するという。

変数はデータに対する付箋のようなものだと理解するとよい。変数はデータを参照するが、変数とデータは実体としては別のものである。

_images/variable.png

Fig. 4 変数のイメージ#

変数を使うと、練習1の答えは次のように求めることができる。

apple = 80
orange = 120

apple * 6 + orange * 9
1560
apple * 0.95 * 6 + orange * 9
1536.0

先ほどと比べると、式の意味が読み取りやすくなっている。一度変数を定義すれば、他のセルからもその変数を使うことができる。 また変数の値は上書きすることもできる。

apple = 100
apple * 6 + orange * 9
1680

さて、先ほど右辺を式と表現したが、例えば次のような定義の仕方もできる。

x = 1 + 1
x
2

次の結果は、やや驚きかもしれない。

x = 2
x = x + 1
x
3

この実行結果の理由は次のとおりである。x = x + 1 のコードにおいて、まず右辺の式が評価される。x の指す値は 2 であるから、x + 1 の値は 3 である。 したがって、x = x + 1 のコードは x = 3 のコードに読み替えられる。その結果として、x は新しい値 3 の名前として上書きされる。数学とは違い x = x + 1 は方程式ではないので注意しよう。

プログラミングでは、このような計算式がよく出てくるので省略記法もある。具体的には、x = x + 1x += 1 と書くことができる。

以下のコードを、結果を予想しながら実行してみよう。

x = 5
x = 2 * x + 1
x
11
x = 9
x /= 3
x
3.0

変数名の付け方#

変数の名前は自由につけることができるが、いくつかルールがある。

  1. 使える文字はアルファベット、数字、アンダースコア( _ ) のみである。

  2. 変数の先頭に数字は使えない。

  3. forif などの文法的に意味のある単語(予約語)は、そのまま単体では使えない。

例えば、price_apple は変数名にできるが、price-apple はエラーになる。a1 は変数名にできるが、1a はエラーになる。 また、if は使えないが、value_if_a は変数名にできる。

変数名はなるべく英語で表現するのが理想的だが、難しければ日本語のローマ字で表現してもよい。 例えば、みかんは英語で書くと mandarin であるが、日本人にとっては mikan の方がわかりやすいだろう。

下のセルを使って、上のルールを確かめてみよう。例えば 1a = 2 などと入力してみよう。

文字列#

これまで数値データを見てきたが、文字もデータとして扱うことができる。

Hello, world!プログラムを思い出そう。Pythonでは両端をシングルクォーテーション( ‘ )またはダブルクォーテーション( ” )で囲うと、文字列データとなる。ただし両端の記号は合わせる必要がある。

'Good morning.'
'Good morning.'

文字列の中で ‘ または ” を使う場合は、両端の記号をそれとは違うものにする。

'She said, "Good morning." '
'She said, "Good morning." '

日本語も扱うことができる。

"太郎"
'太郎'

先ほど学んだ変数を使ってみよう。

name = "次郎"
name
'次郎'

文字列においても + 演算子を使うことができる。文字列の場合は、連結を表す。

greeting = "おはよう、" + name + "さん"
greeting
'おはよう、次郎さん'

f文字列#

上の greeting で行ったように、変数と組み合わせて表示用の文字列を加工する操作はよく行われる。 このとき便利なのがf文字列である。 これについては実際に使っているところを見せるのが早いだろう。

greeting = f"おはよう、{name}さん"
greeting
'おはよう、次郎さん'

普通の文字列との違いは、先頭に f がついていることである。このとき波括弧 { } で囲った部分は式と見なされ、評価した結果の値に置き換えられる。例えば変数の場合は、それの指し示すデータに置き換えられる。

name = "太郎"
greeting = f"おはよう、{name}さん"
greeting
'おはよう、太郎さん'

数式の場合の例を次に示す。

f"7 割る 3 = {7//3} 余り {7%3}"
'7 割る 3 = 2 余り 1'
f"3の平方根の値は{3**0.5}である"
'3の平方根の値は1.7320508075688772である'

小数の表示を第2位までにするには、{式 : .2f} と書く。

f"3の平方根の値は{3**0.5:.2f}である"
'3の平方根の値は1.73である'

表示の整形のための記法は他にも色々とある。必要となったときに逐一調べると良いだろう。

Pythonのバージョン

f文字列は、Pythonのバージョン3.6から利用可能になった機能である。 Google Colab以外の環境ではPythonのバージョンが3.6未満のこともあるが、そのときはPythonをバージョンアップしてからf文字列を利用する必要がある。

エスケープシーケンス#

文字列データで改行を表したいとする。愚直に書くと次のようにエラーになる。

message = "こんにちは。
今日の気温は15度です。"
  File "/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/4098129477.py", line 1
    message = "こんにちは。
                     ^
SyntaxError: EOL while scanning string literal

改行を表現するにはエスケープシーケンスを用いる。まずは次の2つを覚えておけばよい。

エスケープシーケンス

意味

\n

改行

\t

タブ

エスケープシーケンスを用いれば、上の例は次のように修正できる。なお、print()を使わないと\nがそのまま表示されてしまうので、ここではprint()を用いる。

message = "こんにちは。\n今日の気温は15度です。"
print(message)
こんにちは。
今日の気温は15度です。

\ と ¥

MacやLinuxにおいて \ に相当する記号は、Windowsでは ¥ になる。Windowsを使っている方は、適宜 \ を ¥ に読み替えてほしい。例えば、改行を表すエスケープシーケンスは、Windowsでは ¥n である。

コードの改行

コードの1行が長くなると、2行に分けて記述したくなることがある。そんなときは文末に\と入力すると、次の行に継続してコードを書くことができる。例えば、

calc = 1 + 2 + \
    3 + 4 + 5
message = "The place is " + \
    "beautiful."

は次のコードと同じ意味になる。

calc = 1 + 2 + 3 + 4 + 5
message = "The place is " + "beautiful."

コメント#

プログラムにはコメントをつけることができる。

# を入力すると、その行のそれ以降の文字はコメントとなり、Pythonの実行対象とならない。

# これはコメントです。

r = 5
pi = 3.14
pi * r ** 2  # 円の面積の計算
78.5

下のプログラムにコメントを書き加えてみよう。

m = (1 + 2 + 3 + 4 + 5) / 5
m
3.0

エラーと対処法#

これまでプログラムを実行してきて、何度かエラーに遭遇したのではないだろうか。 エラーの原因をつきとめて修正する作業のことをデバッグという。

ここではよくあるエラーを紹介する。 原因を考えながらエラーメッセージを読み、デバッグしてみよう。

例1: 誤字

primt("Hello, world!")
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/1762608797.py in <module>
----> 1 primt("Hello, world!")

NameError: name 'primt' is not defined

エラーメッセージには、primtという変数は定義されていないと書かれている。 このような場合は、タイピングミスをしていないか確認しよう。

例2: 全角文字

print("Hello, world!")
  File "/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/1922743172.py", line 1
    print("Hello, world!")
                         ^
SyntaxError: invalid character ')' (U+FF09)

エラーメッセージには、無効な文字 ‘)’ があると書かれている。このような場合は、全角文字を使っていないか確認しよう。

全角文字にまつわるエラーは、目で見てもよくわからないことがあるので厄介である。 次のエラーの原因がわかるだろうか?

print("Hello, world!") 
  File "/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/2817388938.py", line 1
    print("Hello, world!")
                          ^
SyntaxError: invalid non-printable character U+3000

例3: インデント

 message = "Hello, world!"
    print(message)
  File "/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/869639648.py", line 2
    print(message)
    ^
IndentationError: unexpected indent

エラーメッセージには、予期せぬインデントがあると書かれている。行頭に空白文字を入れて、字下げを行うことをインデントと言う。 Pythonではインデントも文法の一部であり、後々if文や、for文などブロックを伴う構文を書くときに重要な役割を果たす。 しばらくはインデントは使わず、左端を揃えてコードを書くようにしよう。

例4: 文法ミス

5{1 + 2 * ((1 + 3 ** 0.5)}
  File "/var/folders/p0/0zrw9jsj03v3vlszs8v3m2p40000gn/T/ipykernel_74739/2823837591.py", line 1
    5{1 + 2 * ((1 + 3 ** 0.5)}
     ^
SyntaxError: invalid syntax

上のコードには、文法ミスが3箇所ある。次の数式を表すように、デバッグしてみよう。

\[ 5\left\{1 + 2\left(1 + \sqrt{3}\right)\right\} \]
  • ミス1: 左かっこ ( と右かっこ ) の数が合っていない

  • ミス2: * が抜けている

  • ミス3: () 以外のかっこが使われている({} は別の意味になる)

5 * (1 + 2 * (1 + 3 ** 0.5))

エラーが解決できなかったら?

もし自力で解決できそうにないエラーに遭遇したら、エラーメッセージを検索してみよう。多くの場合、解決のためのヒントが見つかるだろう。

演習#

課題1
最初の2つは1で、3つ目以降は「前の2つを足したもの」になる数列のことをフィボナッチ数列という。 初項から順に以下のようになる。

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...

フィボナッチ数列の \(n\) 番目の数は、次のように書けることが知られている。

\[ F_n = \frac{1}{\sqrt{5}}\left\{\left(\frac{1 + \sqrt{5}}{2}\right)^n - \left(\frac{1 - \sqrt{5}}{2}\right)^n\right\} \]

この公式を用いて30番目の数を求めて、結果の整数を提出しなさい。

なお式の途中に小数の現れる計算では、小さな誤差が生じることがある。計算結果にわずかな小数が含まれると思うが、四捨五入して整数部分を答えればよい。 ヒント: 答えの下2桁は40

テスト

結果のわかっている場合を例に、プログラムの正しさを確かめることをテストという。 上の例では、\(n = 10\) までの結果は例として与えられているので、これらを用いてテストできる。 テストしやすくするためにも \(F_n\) の式は変数 \(n\) を使った形で記述するとよい。