2. 変数を評価する

2.1. 計算してみよう

コンピュータは、その名前が由来する通り、計算機です。 計算することは、プログラミングの基礎となります。

まず、コンピュータに計算させることを学びます。

今回もColabを使いながらハンズオン演習していきましょう。

0228d0c04d66449fb03bb0235bd512a8

2.1.1. 数式とプログラミング

Pythonは、できる限り新しいことを覚えなくても プログラムを書けるように工夫されて作られています。 だから、数式を計算するとき、中学校から習ってきた数式をほぼそのまま使えるようになっています。

数式

Python

説明

\(x+y\)

x + y

x に y を足した値(加算)

\(x-y\)

x - y

x から y を引いた値(減算)

\(x \times y\)

x * y

x に y を掛けた値 (乗算)

\(x^y\)

x ** y

x の y 乗(冪乗)

\(x \div y\)

x / y

x を y で割った値

\(\lfloor x / y \rfloor\)

x // y

x を y で割った商(小数点以下切り捨て)

\(\lceil x / y \rceil\)

(x+y-1)//y

x / yの切り上げ

\(x \mod y\)

x % y

x を y で割った余り

ちなみに

演算子の記号が多少、異なるのは、コンピュータ上で扱える文字コードに制限があったからです。 記号の違いに意味はありません。

例題(四則演算)

次の計算をしてみよう

  1. \(1\times2+3\)

  2. \((1+2)\times3\)

  3. \(7\)\(2\) で割った商(小数点以下切り捨て)

  4. \(2^3\)

  5. \(\sqrt{2}\) (ヒント: \(2^{\frac{1}{2}}\))

34c9d77d59e446d4bffd2b6f325f97dd

(正解) \(1\times2+3\)

[7]:
1 * 2 + 3
[7]:
5
[19]:
1*2+3    # 空白は省略してもよい
[19]:
5

(正解) \((1+2)\times3\) : 優先したい演算は\(( )\)で囲みます

[8]:
(1 + 2) * 3
[8]:
9

(正解) 7 を 2 で割った商(小数点以下切り捨て)

[9]:
7 // 2
[9]:
3
[20]:
7 / 2   # 小数点以下も求めるとき
[20]:
3.5

(正解) \(2^3\)

[10]:
2 * 2 * 2
[10]:
8
[11]:
2 ** 3
[11]:
8

(正解) \(\sqrt{2}\)

[12]:
2 ** (1/2)
[12]:
1.4142135623730951

Let’s try

2 ** (1//2) が、正しく \(\sqrt{2}\) にならない理由を考えてみよう

2.1.2. 整数と浮動小数点数

浮動少数点数(float)は、コンピュータ上で実数を擬似的に表現する値です。 Pythonの上では、整数(int)と浮動小数点数はしっかり区別されます。

int-float-fs8.png

2.1.3. 関数による計算

Pythonでは、複雑な計算は関数を用いて行います。

関数は、後から述べる通り、自分で定義して利用することができますが、 既に定義されている便利な関数を利用することもできます。

まずは、便利な関数を利用する方法を覚えましょう。

数式

Python

説明

\(\|x\|\)

abs(x)

x の絶対値

\(\mathrm{max}\{x, y\}\)

max(x,y)

xとyの最大値(大きい方の値)

\(\mathrm{min}\{x, y\}\)

min(x,y)

xとyの最小値(小さい方の値)

\(\sqrt{x}\)

math.sqrt(x)

xの平方根

\(\lceil x \rceil\)

math.ciel(x)

xの(小数点以下)切り上げ

\(\lfloor x \rfloor\)

math.floor(x)

xの(小数点以下)切り捨て

\(x!\)

math.factorial(x)

xの階乗

\(\mathrm{GCD}(x, y)\)

math.gcd(x,y)

xとyの最大公約数(G.C.D.)

import math

math.sqrt(x)のようにmath.で始まる関数は、import mathをしてから使います。

import math
math.sqrt(2.0)

例題(関数による計算)

Pythonを用いて、次の値を計算をしてみよう

  1. \(-1\)\(8\)の差の絶対値

  2. \(3^5\)\(5^3\)の大きい値

  3. \(2, 3, 8\)の最小値

  4. \(\sqrt{3}\)

  5. 465と360の最大公約数

  6. \(7/2\) の(小数点以下)切り上げ

67341beabc8b4890893bd5204bf0577c

(正解) −1と8の差の絶対値

[21]:
abs(-1 - 8)
[21]:
9
[23]:
max(3**5, 5**3)
[23]:
243
[24]:
min(2, min(3, 8))
[24]:
2
[25]:
import math
math.sqrt(3)
[25]:
1.7320508075688772
[26]:
math.gcd(465, 360)
[26]:
15

Let’s try

算術ライブラリには、さまざまな算術関数が用意されています。 どのような関数があるか調べてみよう。

2.2. 式と評価

プログラミングでは、数だけでなく、様々なデータや情報を値として扱うことになります。 だから、数式とは呼ばず、単に式(expression)と呼びます。

式(expression)

式は、プログラムの最小単位

ここまでは、簡単なプログラムとして数式を計算してきました。 ここで「計算」という用語は、プログラムの実行として、少し誤解を与える可能かもしれません。 なぜなら、\(2\times3 = 2 + 2+ 2\) のような展開も(人によっては)計算と見なすかもしれないからです。

コンピュータ科学では、プログラムにおいて計算した結果を値として得ることを 「評価する」という用語を用います。

プログラミングに限らず、専門分野を学ぶときは用語の意味を抑えることが大切になります。 用語の使い方が、曖昧だと解説がよくわからなくなります。

式とは

評価して値が得られるプログラムのこと (値も式の一種としてみなします。)

2.2.1. プログラムの意味★

これからプログラミングを学んでいったとき、 解説を読んでもプログラムの意味がよくわからないこともあります。 そのようなときは、*式を評価した結果が予想できるかどうか確認しましょう。

意味がわかるとは

(式から)評価される値が正しく予測できること

プログラミング言語は、人間とコンピュータの共通言語となります。 両者の解釈が一致するように、意味も理論的に研究されてきて、 知識や意味、学習などを研究するのは、コンピュータ科学の重要なテーマです。

ちなみに、「評価される値が正しく予測できれば意味がわかっている」というのは、 操作的意味論(operational semantics)に基づく考え方です。

Colabは、簡単に様々なプログラムを評価して、その結果を試せるようになっています。 理屈で考えてもわからない時は、手を動かしてみて、Colabで評価してみることをお勧めします。 何回か実行してみると、少しずつ意味がわかってくることも少なくありません。

2.3. 変数

プログラミングでは、数学と同じく、変数を使うことができます。

\(x+1\)

変数は、数学の変数に由来していますが、プログラミングの変数は数学の変数とは意味が少し異なります。 混用すると、高校数学の理解が少し怪しくなるので注意しましょう。

2.3.1. 変数は値の名前

(Pythonの)変数は、値につけられた名前です。

[13]:
x = 1

1という値に変数名x という名前をつけています。

数学でも円周率(\(\pi\))や自然対数の底(\(e\))のように名前をつけて値を扱うことがありました。 プログラミングでは、 同じ要領で、利用者が自由に名前をつけられるようになっています。

2.3.2. 変数の評価

変数は、式(の一種)なので評価することができます。 評価すると、名付けられた値が得られます。

[14]:
x
[14]:
1

変数を計算式の一部に用いることもできます。

[15]:
x + 1
[15]:
2

2.3.3. 変数と式

それでは、次のような応用問題の場合を考えてみましょう。

\(y = x + 1\)

数学の場合は、\(y\)\(x\)の関数であると解釈します。 プログラミングでは、変数は、あくまでも値に対する名前です。

そのため、先にx + 1を評価し、その評価された値にyという名前をつけることになります。

2.3.4. 評価の順序

プログラムは、見てきた通り、評価する順番が決まっています。 プログラムが複数行にわたるとき、上から順番に評価されます。

[16]:
x = 1
y = x + 1
x + y
[16]:
3

Colabは、最終行の式を評価した値のみ表示します。

途中のxyの値も表示したいときは、明示的に値を出力するprint(x)を用います。

(print()は、次節の入出力で詳しく説明します。)

[17]:
x = 1
print(x)
y = 2
print(y)
x + y
1
2
[17]:
3

2.3.5. 再代入(破壊的な代入)

Python では、一度名付けた変数であっても、別の値に同じ名前を付ける}こともできます。

x = x + 1

数式 \(x = x + 1\)というのは、明らかに矛盾していますが、 Pythonとしては「x + 1を評価した値に(もう一度)xという名前をつける」と解釈します。 見方を変えれば、再代入は変数の値を変更していることになります。

さて、名前を付け替えるにしても、変数の値を変更するにしても、なんか紛らわしいですよね。 再代入を多用すると、プログラムが理解しにくくなります。

2.3.6. 変数値の増減

Pythonでは、変数の値を増やしたり、減らしたり、変更することが多くあります。 そのような場合は、自己代入演算子を用いて書くこともできます。

別の書き方

意味

x += 1

x = x + 1

変数xを1つ増やす

x -= 1

x = x - 1

変数xを1つ減らす

x *= 2

x = x * 2

変数xを2倍にする

x //= 2

x = x // 2

変数xを半分にする

2.4. エラー対策に強くなろう

プログラミングは、いつも正しく動作することが続きません。

43a09f018103418f8123f338f5fe2489

むしろ、ほとんどの場合は正しく動きません。 エラーメッセージ等を見ながら、正しく動作するようにするのがプログラミングです。

初学者にありがちなよく間違えるエラーを集めてみました。

Let’s try

是非、エラーを取り除いて正しく動作するようにしてみましょう。

``ハロー世界``と出力したいのに..

[18]:
print("ハロー世界”)
  File "<ipython-input-18-ebacb868980e>", line 1
    print("ハロー世界”)
                  ^
SyntaxError: EOL while scanning string literal

cをa+bの和にしたいのに..

[11]:
c = a + b
a = 1
b = 2
c
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-11-9d58a6438586> in <module>
----> 1 c = a + b
      2 a = 1
      3 b = 2
      4 c

NameError: name 'a' is not defined

xとyの積を求めたいのに ..

[12]:
x = 1
y = 2
xy

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-12-08be3c37ed82> in <module>
      1 x = 1
      2 y = 2
----> 3 xy

NameError: name 'xy' is not defined

BMI が正しく計算されない…

[13]:
height = 1.75
weight = 68.5
BMI = wieght / height * height
BMI
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-13-fc8a82a1dce7> in <module>
      1 height = 1.75
      2 weight = 68.5
----> 3 BMI = wieght / height * height
      4 BMI

NameError: name 'wieght' is not defined

エラーメッセージは英語

英語を読めば解決の手がかりは得られます。 英語が苦手な場合は、機械翻訳を使ってもいいからちゃんと読みましょう。

google_translation.png

2.5. 演習問題

プログラミングは、練習した時間、解いた問題数だけ上達します。がんばりましょう!!

課題リストより

問題の難易度について

本日の内容で解けそうな問題を選んでいますが、 時々、地雷のように難しい問題が混ざってしまいます。 難しい問題を見つけたら授業感想等で報告してください。