Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python...

37
Title プログラミング演習 Python 2019( コラム編 ) Author(s) 喜多, 一 Citation (2020): 1-200 Issue Date 2020-02-13 URL http://hdl.handle.net/2433/245698 Right 本書はCC-BY-NC-NDライセンスによって許諾されていま す。ライセンスの内容を知りたい方は https://creativecommons.org/licenses/by-nc-nd/4.0/deed.ja で ご確認ください。 Type Learning Material Textversion publisher Kyoto University

Transcript of Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python...

Page 1: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

Title プログラミング演習 Python 2019( コラム編 )

Author(s) 喜多, 一

Citation (2020): 1-200

Issue Date 2020-02-13

URL http://hdl.handle.net/2433/245698

Right

本書はCC-BY-NC-NDライセンスによって許諾されています。ライセンスの内容を知りたい方はhttps://creativecommons.org/licenses/by-nc-nd/4.0/deed.ja でご確認ください。

Type Learning Material

Textversion publisher

Kyoto University

Page 2: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

プログラミング演習 Python 2019

コラム編

京都大学 国際高等教育院 喜多 一

Version 2020/02/13

Page 3: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

0 目次 次の章へ 目次へ

2

目次

0. コラム 0 始まり ............................................................................ 4

0.1 Python は 0 ではじまる ............................................................ 4

0.2 1 始まりではいけないのか ........................................................ 4

0.3 結局は ........................................................................................ 5

1. コラム Float って? ...................................................................... 6

1.1 浮動小数点数 .............................................................................. 6

1.2 2進数で浮動小数点数を扱うことの嫌な点 ............................... 7

参考文献 ................................................................................................. 7

2. コラム ニュートン法 ..................................................................... 8

2.1 ニュートン法 .............................................................................. 8

2.2 𝐧 乗根を求める .......................................................................... 9

2.3 平均律 ........................................................................................ 9

3. コラム 相対精度 .......................................................................... 10

3.1 数値の精度 ............................................................................... 10

3.2 絶対精度と相対精度 ................................................................. 10

4. コラム 仮引数と実引数 ............................................................... 12

5. コラム 変数のスコープ ............................................................... 14

5.1 ローカル変数=捨てる変数 ...................................................... 15

5.2 Python での変数のスコープ ..................................................... 15

6. コラム 乱数 ................................................................................. 16

6.1 コンピュータと乱数 ................................................................. 16

6.2 使いたい乱数 ............................................................................ 16

6.3 Random モジュールを使う。 .................................................... 17

6.3.1 乱数の「種」を与える。 ....................................................... 17

6.3.2 整数乱数をつくる .................................................................. 17

6.3.3 並べ替えを作る ..................................................................... 17

6.3.4 実数乱数をつくる .................................................................. 18

6.4 一定の確率で実行する ............................................................. 18

Page 4: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

0 目次 次の章へ 目次へ

3

6.5 Numpy での乱数生成 ............................................................... 18

7. コラム 再帰 ................................................................................. 19

7.1 数式を処理すること ................................................................. 19

7.2 関係代名詞 ............................................................................... 19

7.3 再帰 .......................................................................................... 19

8. コラム GUI .................................................................................. 23

8.1 GUI とは .................................................................................. 23

8.2 使いやすさの裏でのソフトウェア開発の大変さ ...................... 23

8.3 排除と包摂 ............................................................................... 24

9. コラム プログラムと日本語 ―終わりそうで終わらない文字

コードとの闘い .................................................................................... 25

9.1 Python では UTF-8 .................................................................. 25

9.2 ソースコード上の文字コード誤り ........................................... 26

9.3 ¥記号に要注意 ........................................................................ 26

10. コラム 名前空間 .......................................................................... 27

10.1 名前の混乱 ............................................................................... 27

10.2 コンピュータの名前空間 .......................................................... 27

11. コラム プログラムの文書化 ........................................................ 29

11.1 プログラムはすぐに分からなくなる ........................................ 29

11.2 プログラムの文書化 ................................................................. 29

11.3 docstring .................................................................................... 29

12. コラム 三角関数 .......................................................................... 30

12.1 ものづくりと三角関数 ............................................................. 30

12.2 波としての三角関数 ................................................................. 30

12.3 波形の違いを音として聞いてみる ........................................... 31

参考資料 ............................................................................................... 33

13. コラム 参照と複製 ...................................................................... 34

13.1 情報の参照と複製、その得失 .................................................. 34

13.2 ミュータブルとイミュータブル ............................................... 35

Page 5: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

0. コラム 0 始まり

0.1 Python は 0 ではじまる

Python で数値の範囲を生成する際に使われる range 関数では range(5) とすると、

0, 1, 2, 3, 4 と 0 から 4 までの 5 個の整数が生成されます。またリスト a = [0, 1, 2]

の要素の先頭は a[0] と添え字に 0 を与えて操作します。C 言語など他のプログラ

ミング言語の経験がなければ奇異に感じられるでしょう。

0.2 1 始まりではいけないのか

我々は日常生活でものを数えるときに 1 から数え始めます。数え終われば最後の

数字が全体の個数になるので好都合です。

ではなぜ、0 から始めるのでしょうか。

1番さんから10番さん用のデータの置き場所があって隣通しの番地がついてい

るとします。データが最初に入っているのは1番さんの番地でこれを a とすると、

2 番さん...10 番さんの番地は a+1, ..., a+9 となります。自分の番号と 1 番さんの番

地に加える数値が 1 ずれるのです。もし 0 番さん~9 番さんでいいなら、n 番さん

の番地は a+n とすっきり計算できます。

また 10 まで数えることを考えます。1, 2, 3, …, 10 となる訳ですが、最後の 10 は

桁上がりが生じて 2 桁必要です。1 桁で扱える数は 0 を含めて 10 通りあるのに、

1 から数えることで 0 を遊ばせる一方で、最後の 10 を表すのに 2 桁必要になっ

てしまいます。

このような理由から計算を機械で支えているコンピュータにとっては 0 から使

い始めることが好都合で、C 言語など多くのプログラミング言語で 0 始まりで使う

慣習ができてきました。もっとも、プログラミング言語としては初期に作られ、今

も科学技術計算で使われている fortran という言語では配列(Python のリストのよ

うに添え字で要素を操作できるデータの形式)の添え字は 1 始まりです。

数学の世界でも自然数の定義に 0 を含めるとする派と含めないとする派がある

ようです。

Page 6: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

0 コラム 0 始まり 次の章へ 目次へ

5

0.3 結局は

「郷に入らば郷に従う」という言葉があります。あきらめて慣れるのが近道ですが、

数学のように 1 始まりの添え字を使う文化をもっている応用領域では注意して使

いましょう。

Page 7: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

1. コラム Float って?

1.1 浮動小数点数

Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

う意味の語ですから、何だろうと思いますよね。実は、小数を扱うデータの型を浮

動小数点数 (floating point number) といい、その頭の語がこの関数名の由来です。

ただ「浮動」する「小数点」と呼ばれても初心者はなんだかわからないかと思いま

す。浮動小数点数と対立する概念は固定小数点数( fixed point number)です。

固定小数点数とは小数点の位置を固定した数値の表現です。例えば整数部8桁、

小数点以下4桁を扱う、±〇〇〇〇〇〇〇〇.〇〇〇〇といった表現をとることです。

しかしながら、科学技術計算では(絶対値の非常に小さい数、例えばプランク乗

数(約 6.62× 10−34 J s )や非常に大きな数、例えばアボガドロ数(約 6.02× 1023 mol−1 )

が用いられます。このような数値を表すには固定小数点数は辛く、表記例のように、

「整数部を1桁として表記した数(仮数)」と「10(基数)のべき乗(指数)」の

積として表すことが効果的です。このような表現をコンピュータ内でも用いていて

浮動小数点数と呼んでいます。すなわち、実際の小数点の位置がふわふわ揺れ動く

数値という意味です。

コンピュータ(や関数電卓)の表示では10のべき乗の指数を上付き文字で表現

するのは煩雑なので、先のプランク乗数やアボガドロ数の数値部分は以下のように

表記されます:

6.62E-34

6.02E23

計算機の能力が低かったころは、浮動小数点数を表すのに4バイトを用いること

が行われていました(単精度浮動小数点数)。しかしながら、これは仮数部の有効数

字が少なく、実用上の精度として問題もありました。そこで、実用上十分な精度の

ある表現として8バイトを用いることも多く、これは倍精度浮動小数点数 (double

precision floating point number) と呼ばれました。C 言語の浮動小数点数演算は倍精

度での計算を標準として実装されましたが、その際のデータの型の名称で float は

単精度の、double は倍精度の浮動小数点数を用いる意味で使われました。 float で

もチンプンカンプンなのに、double って、と思う方もおられるでしょう。

Python では倍精度の浮動小数点数が一般に用いられていますが、文字列からの変

Page 8: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

1 コラム Float って? 次の章へ 目次へ

7

換の関数は float と命名されています。

1.2 2進数で浮動小数点数を扱うことの嫌な点

高速な計算を実現するために、コンピュータ内部では基数を 10 とする 10 進数で

はなく、2 とする 2 進数が広く用いられています。整数を扱う際には 10 進数も 2 進

数も本質的な違いはありませんが、小数では差異が出てしまいます。

10 進数の小数では 1/3 は 0.33333… となり有限の桁数では表せません、これは十

進数の小数が各桁の大きさ 1/10, 1/100, 1/1000 … のそれぞれ 0 ~9 倍の和として

表そうとするためです。小学校で習ったときには違和感を持たれた方も少なくない

と思いますが、もう慣れましたよね。

2 進数の小数では 1/2, 1/4, 1/8, 1/16 …が各桁の大きさとなり、その 0 倍か 1 倍の

和で数値を表します。このため、10 進数を使う我々がしばしば用いる 0.1 が2進数

では正確に表せません。小学校の時の違和感がコンピュータのおかげで私たちが日

常的に用いる 10 進数の扱いで生じるのです。

実際、Python で 0.1 を 3 回加えたものが 0.3 と等しいかどうかを評価する以下

の式について試してみると

0.1 + 0.1 + 0.1 == 0.3

その値は False となってしまいます。

科学や技術の計算では、十分な精度さえあればよい場合がほとんどで 0.1 が厳密

な値をとっていることはあまり問題になりません 1。しかしながら、お金を扱う会計

計算では、金額としてかなりの桁数を扱う一方で、金利が 0.01 (1%) など、10 進数

の小数で扱われることが多いです。このため、十進数の小数が正確に表せないこと

は避ける必要がでてきます。会計にコンピュータを用いるためには、コンピュータ

内部でも 10 進数の計算をすることが求められるのです。Python では正確な 10 進

数で演算する decimal というモジュールが用意されています。

参考文献

15. 浮動小数点演算、その問題と制限、Python チュートリアル

https://docs.python.jp/3/tutorial/floatingpoint.html

1 科学や技術で扱うのは実際の物理的な存在なので、実現可能な精度が十分に表せればいいのです。正確に長さ 1m の棒を作るとして、どの程度の精度を出せるかを想像してみてください。

Page 9: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

2. コラム ニュートン法

この科目の最初の部分で平方根の近似値を求める計算を行いました。ある数 𝑎 の

平方根 √𝑎 の近似値 𝑥𝑖 について

𝑥𝑖+1 =𝑥𝑖 + 𝑎/𝑥𝑖

2

という式(漸化式)で更新してゆくというものです。式は単純で、収束も速いので

すが逆数を記録する必要があるので手や電卓で計算したりするときには面倒です。

2.1 ニュートン法

この手法について、授業資料では直感的な説明を行いましたが、これは 𝑎 の平方

根を求める方程式

𝑓(𝑥) = 𝑥2 − 𝑎 = 0

の解をニュートン法(名称の由来はもちろん、アイザック・

ニュートンです。ニュートン・ラフソン法とも呼ばれます)

と呼ばれる手法で求めるアルゴリズムになっています。

ニュートン法では、方程式 𝑓(𝑥) = 0 の近似値 𝑥𝑖 につい

て、𝑓(𝑥) 上の点 (𝑥𝑖 , 𝑓(𝑥𝑖)) で 𝑓(x) の接線を引き、それと

𝑥 軸との交点を次の近似値とします。接線の方程式は

𝑦 − 𝑓(𝑥𝑖) = 𝑓 '(𝑥𝑖)(𝑥 − 𝑥𝑖)

ですから 𝑦  =  0 として 𝑥 について解くと

𝑥 = 𝑥𝑖 −  𝑓(𝑥𝑖)

𝑓'(𝑥𝑖)

を得ます。これを xi+1 とするので

𝑥i+1 = 𝑥𝑖 −  𝑓(𝑥𝑖)

𝑓′ (𝑥𝑖)

を得ます。平方根を求める場合には 𝑓(𝑥) = 𝑥2 − 𝑎 を当てはめると冒頭の漸化式を得

ます。

𝑥𝑖+1 = 𝑥𝑖 −𝑥𝑖

2 − 𝑎

2𝑥𝑖=

𝑥𝑖 + 𝑎/𝑥𝑖

2

-2

-1

0

1

2

3

4

0 1 2 3 4𝑥𝑖

𝑥𝑖+1

Page 10: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

2 コラム ニュートン法 次の章へ 目次へ

9

2.2 𝐧 乗根を求める

ちなみに 𝑛 乗根を求めたい場合は

𝑓(𝑥) = 𝑥𝑛 − 𝑎 = 0

として同じように漸化式を得ると

𝑥𝑖+1 =(𝑛 − 1)𝑥𝑖 + 𝑎/𝑥𝑖

𝑛−1

𝑛

を得ます。これは近似値 𝑥𝑖 とそれから計算したもう一つの近似値 𝑎/𝑥𝑖𝑛−1 を 𝑛 −

1 :  1 に内分した点になっています。この式での計算のプログラミングは容易ですの

でぜひ挑戦してみてください。

2.3 平均律

n 乗根と言われてもなじみがないかもしれませんが、音楽の音階では 12 乗根が

使われます。音階で1オクターブ離れた音は周波数が 2 倍になります。私たちが不

通に使っている平均律と呼ばれる音階では 1 オクターブを 12 の半音に割っています

が、半音異なる音程は周波数が 2 の 12 乗根(約 1.059)だけ異なるように構成さ

れています。和音をきれいに響かせるためには音程が整数比になっていることが望

ましく、このように作られた音階を純正律というのですが、半音間の周波数比がば

らついてしまい、転調などがしにくいことが問題になります。平均律は和音の多少

の濁りを許して近似することで使いやすくした音階です。

Page 11: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

3. コラム 相対精度

3.1 数値の精度

理科では有効数字を気にして計算をしていたかと思います。自然科学では実験や

観測で得られる計測値には誤差が含まれているためです。例えば、円の半径を計測

して 𝑟  =  3.456 mという値で表記されているということは小数点以下 3 桁の「6」と

いう数値までが意味があるということを表しています。すなわちそれ以下の桁が四

捨五入されていることから測定値𝑟は

3.4555 m  ≤  𝑟  < 3.4565 m

を表し、不確かさの幅は 3.4565 m  −  3.4555 m  =  0.001 m, すなわち 1mm というこ

とになります。

同じ計測法で同程度の範囲を図れば 1mm 程度の誤差があるということになりま

す。

これに対して、この円の外周の長さは 𝐿  =  2 𝜋𝑟で与えられますから計算すると

21.7115m  ≤ 𝐿  <  21.7178 m

となり、その誤差は 0.001  × 2 𝜋 ~ 0.00628 となります。この場合、正確な定数 2 𝜋 を

掛けるので誤差の絶対値は変わりますが、𝐿 の値との比率は 0.001 と変わりません。

理科の計算で有効数字の桁数に留意して計算する理由はここにあります。計算を簡便

に行うために正確に比率を吟味する代わりに、桁数で考えているのです。

3.2 絶対精度と相対精度

コンピュータを使った数値の計算では真の値に収束する数列などを使って近似計算

します。この場合も、計算をどこで打ち切るかは必要な計算の精度から決まります。

例えば、真の値に収束する数列 𝑎1, 𝑎2, ⋯ → 𝑎 を用いて 𝑎 の近似値を計算することを

考えます。仮に 𝑎𝑖 の下限 𝑎𝑖𝐿 と上限 𝑎𝑖

𝑈 も与えられているとすると、aiの精度は

𝑎𝑖𝑈 − 𝑎𝑖

𝐿

となります。この値が 0.001 より小さくなれば計算を終了させる、すなわち

𝑎𝑖𝑈 − 𝑎𝑖

𝐿 ≤ 0.001

とすれば、計算の精度は 0.001 という絶対的な値になります。

Page 12: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

3 コラム 相対精度 次の章へ 目次へ

11

しかしながら、例えば平方根の計算を考えると 10000 の平方根は 100 ですので、

0.001 という絶対的な精度はかなり高いのに比べ 1/10000 の平方根は 1/100 = 0.01

ですので、0.001 の精度というのはかなり悪いことになります。

そこで、計算で得られる値に対して、一定の比率 (例えば 0.001)の精度を要求すると

すれば、そのための判定条件は

𝑎𝑖𝑈 − 𝑎𝑖

𝐿 ≤ 𝑎 × 0.001

となり、両辺を 𝑎 で割れば

𝑎𝑖

𝑈 − 𝑎𝑖𝐿

𝑎≤ 0.001

で判定することになります。ただし真の値 𝑎 は分かりませんので、実際に得られて

いる計算値 𝑎𝑖 を用いて

𝑎𝑖

𝑈 − 𝑎𝑖𝐿

𝑎𝑖≤ 0.001

で判定することになります。このように相対精度で計算を終了させることは、理科

の計算で行う有効数字の考え方を数値の近似計算に適用したものと言えます。

Page 13: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

4. コラム 仮引数と実引数

Python で関数を呼ぶ例を考えてみましょう。

# ここは関数定義

def square(x):

return x*x

# ここは呼び出し側

y = 2

y2 = square(y)

print(y)

関数 square() は引数 x をとり、呼び出す側では変数 y を引数として関数

square() を呼んでいます。関数定義内の引数を特に「仮引数」、呼び出し側の引数を

「実引数」と呼びます。

英語ではそれぞれ parameter (あるいは formal parameter), argument (あるいは

actual parameter) と呼びます。初学者は呼び出す側と呼び出される側で引数の名前が

異なることで混乱するかもしれません。

しかしながら、実世界でも同じようなことは使われています。

たとえば、食堂などで料理を注文することを考えてみましょう。以下のような会

話はしばしば聞かれるものです:

ウェイター:いらっしゃいませ、ご注文は?

客 B さん:トンカツ定食

ウェイター:かしこまりました。トンカツ定食ですね。

ウェイター、厨房まで移動

ウェイター:3番テーブルさん、トンカツ定食

料理人:3番テーブル、トンカツ定食了解

実際のところ、食堂の従業員にとって、(よほどの馴染みのお客さんでもなければ)、

Page 14: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

4 コラム 仮引数と実引数 次の章へ 目次へ

13

お客さんの名前はどうでもいいことです。そこで客を特定するのに、「〇番テーブル」

という表現を用いています。これが食堂での仮引数と言えます。

仮引数を用いることで、食堂の側は業務の遂行が定型化でき、業務効率が上がり

ます。客の側も食堂内で自分がどのように特定されているかはそれがうまく隠蔽さ

れていれば問題ではないでしょう1。

プログラミング言語は、人が計算機を動かす命令をいかに容易に書けるか、とい

うことで開発されてきました。その結果、現実社会での人の行動と類似したやり方

が用いられるのだと考えられます。

1 「3番テーブル」という呼称で呼ばれるのは、それを聞かされるなら、あまりいい気がしない人もいるかもしれません。飛行機でビジネスクラスなどを利用すると、キャビンアテンダントに実名で呼ばれることがあります(運行管理上、チケットは実名で購入しています)。これはその客さんを大事にしているというサービスです。

Page 15: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

5. コラム 変数のスコープ

プログラミング言語で使っている変数が「どの範囲まで見えているか」、を「変数

のスコープ」といいます。

実世界で以下のようなことを考えてましょう。

資料などを作成する際には多くのメモなどがその途中で発生します。資料

の作成の一部を部下に頼んだとします。

上司 A さん:B 君、すみませんが、この資料の図3の作成をお願いできま

すか。

部下 B 君:わかりました、A さんの作業台で作業すると資料など参照しや

すいので、そこで作業していいですか。

A さん:いいですよ。使ってください。

B 君は、さまざまなメモをつくりながら、図3を完成させる。

B 君:A さん、図3ができました。じゃあ僕はもとの仕事にもどります。

A さん:ありがとう、たすかったよ。

B 君、そのままたちさる。

A さん:あいつ作業メモそのままにしてあるじゃないか。もとの資料と区別

がつかん。困った。

さて、B 君はどうすればよかったでしょう。以下のようなことをすれば A さんを

困らせずにすみます。

作業が終了したら自分の作ったメモは捨てる。

そのために、A さんの資料とメモを区別できるように、メモは専用の用紙をつかう。

あるいは、A さんの資料のない作業台にメモを置く

Page 16: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

5 コラム 変数のスコープ 次の章へ 目次へ

15

5.1 ローカル変数=捨てる変数

プログラミング言語では関数などを呼び出すことで多くの仕事を下請けに出して

しまいます。このときに、先の例での B 君のメモに相当する関数内で利用する変数

はローカル変数として別に確保し、終了時に捨ててしまいます。関数の外側からは

ローカル変数は見えないようになっています。

5.2 Python での変数のスコープ

変数のスコープはプログラミング言語によって異なります。Python では

⚫ 関数内の変数(ローカル変数)は外側から見えません。

⚫ 関数内から外側で定義されたグローバル変数は読むことだけできます。

⚫ 関数内からグローバル変数に書き込むためには global 文で宣言しないといけ

ません。

⚫ for 文のインデクス変数は for 文終了後も残ります。

Page 17: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

6. コラム 乱数

6.1 コンピュータと乱数

コンピュータはプログラムで記述された動作を正確に実行します。コンピュータ

で数値の系列を生成することを考えると、プログラムと変数の値から、次に生成す

る系列の値は正確に予測できることになります。一方、乱数列とは「でたらめ」な

数の列のことです。このため、外部からランダムな要素を持ち込むなどしない限り、

本質的にはプログラムで乱数列は生成できません。

コンピュータで生成される乱数列は「ランダムっぽく見える」数列で正しくは「疑

似乱数列」と呼ぶべきものです。生成される乱数列の良さはアルゴリズムによって

定まりますが、さまざまなテストで、どのような意味で良い乱数列が生成されるの

かを検討します。

コンピュータの応用では乱数はさまざまな所で使われます。皆さんにとって馴染

みのあるものはゲームでしょうし、学術研究ではシミュレーションなどで多用しま

す。乱数系列の発生では乱数系列を再現できるかどうかが問題になります。ゲーム

だと系列を再現できると面白さがなくなります。そこで、乱数系列の生成の初期値

にコンピュータの時計を使ったりします。他方、学術研究では、同じ系列を再現で

きないと作業効率が落ちますし、他の方に追試してもらえません。そこで明示的に

初期値を与えて乱数系列を作るようにします。

6.2 使いたい乱数

さまざまなプログラムを書いていて使いたくなる乱数としては以下のようなもの

があります。

⚫ 整数の乱数

➢ 一様乱数、サイコロの目のように一定の範囲で同じ確率で生じる乱数

➢ 特定の分布に従う乱数、例えば二項分布やポアソン分布に従う乱数

⚫ 浮動小数点数の乱数

➢ 一様乱数

➢ 特定の分布に従う乱数、典型的には正規分布ですが、このほかにも様々な

Page 18: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

6 コラム 乱数 次の章へ 目次へ

17

分布に従う乱数が必要になります。

⚫ 並べ替え

リストなどのランダムな並べ替え、抽選のように一定数をランダムになおかつ

重複なく選びたい場合があります。

6.3 Random モジュールを使う

Python の乱数発生用モジュールとして random モジュールがあります。メルセ

ンヌツイスターと呼ばれるよくテストされた手法で乱数を生成します。なお、セキ

ュリティ用途にはより安全な secrets モジュールを使うことが推奨されています。

6.3.1 乱数の「種」を与える。

⚫ random.seed()

乱数系列を発生させるための種を与える関数です。引数がなければ種としてシステム

の時計を使います。整数型の引数を与えると、それを種として乱数系列を開始します。

6.3.2 整数乱数をつくる

⚫ random.randrange(stop)

引数は range() 関数と同じで、range() 関数で生成される範囲の整数乱数を生成し

ます。 例えば random.randange(5) は 0 から 4 の乱数を生成します。

⚫ random.randint(a, b)

a から b までの整数乱数を発生します。a も b も発生される乱数に含まれます。

6.3.3 並べ替えを作る

⚫ ramdom.sample(population, k)

母集団 population を並べ替えて k 個を取り出します。母集団には range() 関数

やリストが使えます。

Page 19: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

6 コラム 乱数 次の章へ 目次へ

18

6.3.4 実数乱数をつくる

⚫ random.random()

0 以上 1 未満の実数の乱数を作ります。

⚫ random.gauss(mu, sigma)

平均 mu, 標準偏差 sigma の正規分布に従う乱数を生成します。

6.4 一定の確率で実行する

プログラムの中で、ある確率(p という変数の値としましょう)で何かを実行した

い場合があります。その時には以下のようにプログラムします

if (p > random.random()):

実行したいブロック

6.5 Numpy での乱数生成

高度な数値計算を支援するライブラリの Numpy では沢山の乱数を一度に発生さ

せることが可能で、計算効率が上がります。多くの関数が定義されています。その

一部は以下のようなものです。

⚫ numpy.random.seed: 乱数の種を与える関数

⚫ numpy.permutation 配列を与えるとそれを並べ替えた新しい配列を作ります

⚫ numpy.random.rand 連続一様分布に従う乱数を指定された個数、生成します

⚫ numpy.random.randint: 整数乱数を生成します

⚫ numpy.random.randn: 標準正規分布に従う乱数を生成します。

Page 20: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

7. コラム 再帰

7.1 数式を処理すること

私たちが日ごろ使う数式では計算の順序を制御するのに括弧()を使います。

1×2 + 3×2 = (1+3)×2

と変形すると、2を掛けるという計算が一回で済みます。そのため、足し算を優先

して行う必要があるので括弧 () の中に足し算を書きます。

括弧はその中にさまざまな数式を書くことができ、さらに内側に括弧があること

を許します。われわれは、括弧が出てくるたびに、それまでの計算を「棚上げ」に

して、括弧の中を計算します。さらに括弧が現れると再度、棚上げして括弧の中を

計算します。

7.2 関係代名詞

英語の一つの文は名詞の主語と動詞を中心に目的語や補語で骨格が構成されます。

名詞を修飾するのが形容詞ですが、形容する方法として関係代名詞があり、関係代

名詞で修飾する部分には、再び主語や動詞が現れ、全体を「関係代名詞節」として

捉えます。先ほどの数式と同じように関係代名詞節のなかに再び、主語(名詞)や

動詞の構造が現れました。読解は難しくなりますが、この節の中の名詞をふたたび、

関係代名詞節で修飾することも可能でしょう1。

I read the book.

I read the book that was referred in a book.

I read the book that was referred in the book that was referred in another book.

7.3 再帰

プログラムで「部分」に対して同じ処理を適用する仕掛けを再帰 (recursion) と呼び

ます。よく用いられる例は階乗の計算です。N の階乗は N が1の時は 1, N が1よ

1 このような文法構造は言語学の分野で、句構造文法と呼ばれます。チョムスキーによって提唱されたものですが、コンピュータでの構文解析にも活用されています。

Page 21: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

7 コラム 再帰 次の章へ 目次へ

20

り大きい(整数の)時は N! = N * (N-1)! と表せます。これをプログラムで書くと以

下のようになります。

def frac(n):

if n==1:

return 1

else:

return n*frac(n-1)

今度は図形で考えてみましょう、以下は Turtle グラフィクスで6角形を描くプログ

ラムです。

from turtle import *

for i in range(6):

forward(100)

left(60)

ここで forward(100) の部分を以下のように変形することを考えましょう。

⚫ 1/3 の長さは直進

⚫ 左へ 60 度回転

⚫ 1/3 の長さで直進

⚫ 右へ 120 度回転

⚫ 1/3 の長さで直進

⚫ 左へ 60 度回転

⚫ 1/3 の長さで直進

このように迂回する関数を作って動かします。

Page 22: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

7 コラム 再帰 次の章へ 目次へ

21

from turtle import *

def detour(L):

LL = L/3

forward(LL)

left(60)

forward(LL)

right(120)

forward(LL)

left(60)

forward(LL)

for i in range(6):

detour(100)

left(60)

さらに、detour の中で forward の代わりに detour を呼ぶようにします。再帰の登

場!です。ただし、長さが 10 以下ならそのまま forward で描画します。

def detour(L):

if (L < 10):

forward(L)

else:

LL = L/3

detour(LL)

left(60)

detour(LL)

right(120)

detour(LL)

Page 23: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

7 コラム 再帰 次の章へ 目次へ

22

left(60)

detour(LL)

このような図形は一部がそれと相似な構造をもち、フラクタル図形と呼ばれます。

自然界には雪の結晶のように、物理的な現象としてこのような構造が現れたり、木

の枝のように生命の形づくりに現れたりします。

Page 24: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

8. コラム GUI

8.1 GUI とは

GUI は graphical user interface の略で、現在のパーソナルコンピュータやスマート

フォンで主に使われるユーザとコンピュータが対話するための環境です。これに対

して conda prompt のような文字入力でコンピュータを操作する環境は CUI,

character user interface と呼ばれます。IDLE の Python シェルは折衷的な存在である

と言えます。

8.2 使いやすさの裏でのソフトウェア開発の大変さ

Tkinter は python で手軽に GUI 型のアプリケーションをプログラムを作成する

環境ですが、実際のプログラミングに際しては、イベント駆動の考え方や、MVC ア

ーキテクチャなどを理解したうえで、ウィジェットの配置、表示、動作など、細か

く指定してゆくことが必要になります。実際にプログラムを書いてみるとプログラ

ミングしなければならないことの多さに気づくでしょう。人に使ってもらうソフト

ウェアの開発にあたっては GUI の開発は全体の工数のかなりの部分を占めるよう

です。

しかも我々が直接プログラミングしているものの背景にはマウスやキーボードの

入力を処理したり、ウィンドウの重なりを処理したりといった膨大な処理をウィン

ドウシステムが実現してくれており、さらに tkinter が Windows, macOS, Linux とい

った OSの違いを吸収する形で python で容易にプログラミングできる環境を提供し

てくれています。

スマートフォンなどタッチパネルを用いた GUI では、さまざまな指での操作(ジ

ェスチャ)を解釈して動作を変えていますし、表示も画面のスクロールやメニュー

の出し入れなども人が使いやすいように細かくプログラムで調整されています。例

えばスクロールした画面が端に達すると単に止まるのではなく、跳ね返るようなア

ニメーションが行われます。もともと画面が跳ね返るようにできている訳ではなく、

人が直感的に理解しやすいように、物理世界で起きそうなことをプログラムでわざ

わざ実現しているのです。

Page 25: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

8 コラム GUI 次の章へ 目次へ

24

8.3 排除と包摂

GUI はコンピュータを直感的に操作することを可能し、その利用を拡大すること

に貢献しました。キーボードでの文字入力が十分に扱えない子供でも GUI ならある

程度操作できます。

他方で、GUI によるコンピュータの利用から排除 (exclude) されている人が居る

ことも理解しておくことも重要です。視覚障害のある方には GUI 環境の利用は困難

ですし、年配の方にはマウスボタンのダブルクリックを難しいと感じる方もおられ

ます。指に障害のある方にはジェスチャを多用するスマートフォンの操作は難しい

のではないでしょうか。

また、GUI は操作を人に教える、という点でも難しい側面があります。文字や言

葉だけではなかなか操作法が伝わりません。コンピュータの利用法を書いた書籍や

雑誌のページ数が多いのは画面を示さなければ操作法が伝えられないからですし、

動画などの助けを借りなければ分からないことも多いかと思います。

「排除 (exclude)」の逆が「包摂 (include)」です。最近ではインクルーシブ・デザ

インと呼ばれるデザイン手法も注目されています。コンピュータは一方でソフトウ

ェアの開発に費用がかかり、その回収も含めて商業主義的に健常者向けに開発され

るものが多いのですが、同時に、適切にプログラミングすることで、より多くの人

を包摂することも可能です。授業で紹介した MVC (model-view-control)アークテクチ

ャでシステムが設計されていれば、コンピュータ担う本質的仕事を model として維

持しながら利用者とのインターフェイスである view や control を利用者に合わせ

て構成しやすくなります。

Page 26: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

9. コラム プログラムと日本語

―終わりそうで終わらない文字コードとの闘い

9.1 Python では UTF-8

コンピュータの上で稼働する OS やプログラミング言語は英語圏で開発されたもの

が多く、アルファベットに比べ数多くの漢字を用いる日本語をコンピュータで用い

ることはどうしても後手に回ってしまいます。

それでも、世界の中で日本語は早くからコンピュータで利用できた言語です(!)。

しかしながら、このことが日本語の文字をコンピュータ上で表す仕組みである「文

字コード」の混乱を生じさせています。マイクロソフト社は早くから日本市場向け

にソフトウェアを販売してきた会社ですが、Windows の前身のオペレーティングシ

ステム MS-DOS では日本語用に Shift-JIS コードという文字コードを採用しまし

た。その後、中国語や韓国語など多数の文字を用いる言語を含めて国際的に利用で

きる文字コードとして Unicode が開発され、Windows でも現在では内部ではこのコ

ードが採用されています。ただ、日本での Windows では、従来のファイルとの互換

性を維持するためファイル名やテキストファイルの文字コードに Shift-JIS コード

が用いられています。Apple 社の Mac も以前は日本向けに Shift-JIS コードを用い

た OS を提供してきましたが、現在では Unicode を用いています。Linux でも近年

では Unicode が標準になっています。

Python も Python 2 では文字コードの扱いに問題があったのですが、Python 3 で

は Unicode を採用していて、 Unicode をコンピュータ内で扱う方法である文字符号

化スキームとして utf-8 を用いています。Windows 環境では Python 自身がファイ

ル名などに shift-JIS コードが使われているという情報を持っており、これにより文

字コードの変換を行ってくれます。

よく、Python のソースコードの冒頭部分に

# -*- encoding: utf-8 -*-

というコメントを見かけます。これは、このソースプログラムが utf-8 で書かれて

いることを Python に示す magic comment と呼ばれるものです。何も書かれていな

い場合も utf-8 であるとして処理されます。

また、このコメントの前に

#!/usr/bin/python

Page 27: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

9 コラム プログラムと日本語

―終わりそうで終わらない文字コードとの闘い 次の章へ 目次へ

26

というものも見かけますが、これはシェバングとよばれ、Linux などの OS のシェ

ルで Python プログラムを直接呼び出した時に起動するプログラムを示すものす。

9.2 ソースコード上の文字コード誤り

Python のソースコードで本来 ASCII コード(いわゆる半角の英数字)で書くべ

ところを漢字コードの同じ文字(いわゆる全角文字)で書いてしまうと見つけにく

いエラーになります。Python では字下げでブロックを表しますが、半角の空白文字

の代わりに全角の空白文字を入れてしまうと見た目が変わらないために分かりにく

いエラーなります。

9.3 ¥記号に要注意

ASCII コードのうち、バックスラッシュはこれまでの日本語のコードでは代わりに¥

記号が割り当てられています。UTF-8 では別途、円記号用にコードが割り当てられ

ているのですが、Windows ではバックスラッシュ用のコード(5C)についても円記

号のフォントで表示します1。英語の資料などでバックスラッシュになっている箇所

を円記号に置き換えて入力します。

他方で Mac では円記号を入力するとバッスラッシュ用のコードではなく、UTF-8

の円記号(A5)で入力され、本来、Python が求めているバックスラッシュ (5C)にはな

りません。このためエラーになりますので、こちらはバックスラッシュで入力して

ください。

1 Windows でも開発環境によっては、バックスラッシュを表示するフォントを選んだりしているようです。

Page 28: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

10. コラム 名前空間

10.1 名前の混乱

名前空間というのは不思議な用語ですが name space の訳で、名前が通用する論理

的な空間というような意味です。

コンピュータについての名前空間の話をする前に、実生活で考えてみましょう。

例えば田中一郎さん、という方がおられるとします。もし名前を使ってこの方を呼

ぶとするなら、家庭内ではたぶん、「一郎」でしょう。田中という姓ではどなたのこ

とかわからないからです。職場では「田中さん」と呼ばれることが多いでしょうが、

同姓の方がおられたら「一郎」さんと呼ばれたり、「田中一郎さん」とフルネームだ

ったりするでしょう。我々は自然とその場で一意になるように名前の呼び方を工夫

しています。

電話番号はどうでしょうか?市内局番、市外局番、国際番号など電話を遠くから

かけるために次第に長い番号をダイヤルしなければなりません。近くなら短い番号

で特定できるように、階層的に番号をつける工夫がされているのです。

10.2 コンピュータの名前空間

コンピュータのプログラムでは多くのオブジェクト(変数とか関数とか)に名前

をつけてアクセスします。ライブラリ(Python のモジュールなど)を使うと、多く

の関数名などを利用しなければなりません。これらを特に階層化もせずに均一な空

間でアクセスできるようにすると、同じ名称を別の意味で使ってしまう名前の衝突

が生じます。そこで、名前の通用する範囲(名前空間)を制限することが必要にな

るのです。たとえば Python の数学ライブラリ math は

import math

として、この中で定義されている円周率は

math.pi

で呼び出します。少し面倒かもしれません。

そこで

from math import *

とすると、「math.」を付けずに利用できます。

Page 29: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

10 コラム 名前空間 次の章へ 目次へ

28

sin(0.5*pi)

など、すっきり計算できて関数電卓代わりに使うのは便利です。ところが math で

は自然対数の底は

e

という変数で定義されています。うっかり e という変数に値を代入してしまうと、

定義が崩れてしまいます。(残念ながら Python は定数の定義を保護する仕掛けがあ

りません)。

このような混乱を招いてしまうことを「名前空間の汚染」と呼びます。名前空間

を汚染しないためには安易な import は控えたほうがよいようです。

Page 30: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

11. コラム プログラムの文書化

11.1 プログラムはすぐに分からなくなる

コンピュータのプログラムは書いた本人でさえ時間が経つとなぜそう書いたのか

が分からなくなります。ましてや、複数人で継続的にプログラムを維持し、改善し

てゆくためには、プログラムについて説明した文書が必要になります。

しかしながらプログラムについての文書を作成することには多くの労力を要しま

すし、プログラムを書いている人にしか分からない事項も出てきます。プログラム

について文書化するもっともよい機会はプログラムを書いている時です。プログラ

マにとっても内容が分かっている時に書けばいいので、やる気も出ますし、作業効

率も上がります。

11.2 プログラムの文書化

文書化の方法としてプログラムを読んで分かりやすくすることがありますが、そ

れには2つの方法があります。

⚫ 一つはプログラムそのものを読んで分かりやすいものにすることです。分かり

やすい変数名や関数名をつけることなどが重要ですが、命名法や大文字、小文

字などの文字使い、用語などを統一的につける「コーディングの慣習」も重要

になります。

⚫ もう一つはプログラムに注釈を入れることです。

11.3 docstring

Python にはプログラムの文書化に関連して docstring という面白い仕掛けが導入

されています。モジュールや関数、メッソドの冒頭にそれを説明する文字列 (docstring)

を定義しておきます。help() 関数は import 文などで読み込んだモジュール、関数な

どについて、この docstring を用いて説明文を作ってくれます。注釈と異なるのは、

プログラムとして定義された文字列ですので、他のプログラムから参照可能である、

という点です。

Page 31: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

12. コラム 三角関数

12.1 ものづくりと三角関数

高等学校で三角関数を習ったときに、なんのために学ぶのかという疑問を持たれ

る方も少なくないと思います。この授業では tkinter のグラフィクス機能を使ってア

ナログの時計を作りました。時計の針を描くためには時刻を角度に読み直したうえ

で、針先の位置の X 座標、Y 座標が必要ですので三角関数は必須のものになります。

三角関数を実用的に初めて使ったという方も少なくないかと思います。

この例のように傾いたものの角度と水平、垂直方向の長さを関係づけるのが三角

関数です。ですから、ものづくりには不可欠な関数になります。

12.2 波としての三角関数

もう一つの例として、周期関数を三角関数の和で表す例を示しました。のこぎり

波や矩形波(方形波)はそれぞれ以下のように三角関数の和として近似されます 1

• 𝑓1(𝑥) =sin(𝑥)

1+

sin(2𝑥)

2+

sin(3𝑥)

3+

sin(4𝑥)

4…  

• 𝑓2(𝑥) =sin(𝑥)

1+

sin(3𝑥)

3+

sin(5𝑥)

5+

sin(7𝑥)

7…  

このような特定の関数を近似する三角関数の和は「フーリエ級数」と呼ばれており、

周期関数なら、その関数の周期の整数分の1の周期(整数倍の周波数)を持つ正弦関

数 sin と余弦関数 cos の定数倍の和(級数)で近似できることが知られています。

1 最大値、最小値が 1, -1 ののこぎり波、矩形波については、この式にそれぞれ係数 2/π , 4/πがかかります。

-2

-1

0

1

2

0 200 400 600 800

系列1 系列2 系列3

系列4 系列5

-1.5

-1

-0.5

0

0.5

1

1.5

0 200 400 600 800

系列1 系列2 系列3

系列4 系列5

Page 32: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

12 コラム 三角関数 次の章へ 目次へ

31

1フーリエ級数の各項の係数はフーリエ級数で表したい関数に、各項の三角関数を掛

けて積分することで求められます。

12.3 波形の違いを音として聞いてみる

音程が同じでも楽器の種類によって音色が異なります。その理由の一つは、楽器

の出す音には音程を表す周波数の正弦波(基本波、基音)に加え、その整数倍の周

波数の正弦波(高調波、倍音)が含まれるためです。これは弦楽器の弦や管楽器の

管が基本波だけでなく、高調波にも共振することによります。

ここでは、コンピュータで合成した波を実際に聞き比べてみましょう。

⚫ sinwavw.wav は周波数 440Hz の正弦波

⚫ harmonics-saw.wav はのこぎり波を第7高調波まででフーリエ級数で近似したも

⚫ harmonics_sq.wav は矩形波(方形波)を第7高調波まででフーリエ級数で近似し

たものです

これらのファイルは wav と呼ばれる形式の音声ファイルです。Python では wave

というモジュールを使って wav 形式にファイルを読んだり、書いたりできます。上

記のデータの生成に用いたプログラムが次の makesoundfile.py です(参考資料[2]

を参考にしました)。

行 ソースコード

1

2

3

4

5

6

7

8

9

10

import numpy as np

import wave

import struct

# 音声ファイル名

fname = 'harmonics-sq.wav'

wf = wave.open(fname, 'w')

# 音声ファイルのパラメータ、1 チャンネル(モノラル)、

# 1 点の音声データ 2byte (16bit)

# サンプリング周波数 44.1 kHz

1 上記の例ではもとの関数が奇関数(グラフが原点に対称)なので、正弦関数( sin)しか現れません。また連続関数である三角関数の和で不連続な関数を近似しようと無理をしているので、関数の不連続点でその無理が現れてしまいます。

Page 33: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

12 コラム 三角関数 次の章へ 目次へ

32

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

ch = 1

width = 2

samplerate = 44100

wf.setnchannels(ch)

wf.setsampwidth(width)

wf.setframerate(samplerate)

# 10 秒間継続

time = 10

numsamples = time * samplerate

print( "チャンネル数 = ", ch)

print( "サンプル幅 (バイト数) = ", width)

print( "サンプリングレート(Hz) =", samplerate)

print( "サンプル数 =", numsamples)

print( "録音時間 =", time)

print( "出力ファイル = ", fname)

# 信号データを作る (numpy の ndarray で)

freq = 440 # 基本周の周波数 freq を 440 Hz にする

x=np.linspace(0, time, numsamples+1) # 0≦t≦time を numsamples 等分

h1=np.sin(2 * np.pi * freq * x) # 基本波の正弦波

h2=np.sin(2 * np.pi * 2* freq * x) # 第2高調波の正弦波

h3=np.sin(2 * np.pi * 3 * freq * x) # 第3高調波の正弦波

h4=np.sin(2 * np.pi * 4 * freq * x) # 第4高調波の正弦波

h5=np.sin(2 * np.pi * 5 * freq * x) # 第5高調波の正弦波

h6=np.sin(2 * np.pi * 6* freq * x) # 第6高調波の正弦波

h7=np.sin(2 * np.pi * 7 * freq * x) # 第7高調波の正弦波

# 基本波と高調波に係数をかけて波を合成

y = h1 + 0*h2/2 + h3/3 + 0*h4/4 + h5/5 + 0*h6/6 + h7/7

y=np.rint(32767*y/max(abs(y))) # [-32767,32767] の範囲に収める

y=y.astype(np.int16) # 16 ビット整数に型変換する

Page 34: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

12 コラム 三角関数 次の章へ 目次へ

33

45

46

47

48

49

50

51

52

y=y[0:numsamples] # numsamples 個のデータに打ち切る

# ndarray から bytes オブジェクトに変換

data=struct.pack("h" * numsamples , *y)

# データを書き出す

wf.writeframes(data)

wf.close()

参考資料

桂田 祐史:Python を使った WAVE ファイルの処理、

http://nalab.mind.meiji.ac.jp/~mk/lecture/fourier-2018/python-sound/ (2018/12/3 アクセ

ス)

Page 35: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

13. コラム 参照と複製

プログラミング言語で利用者が注意すべきことはしばしば変数が扱う情報そのも

のではなく、実際の情報の所在への「参照」を持つことです。Python では変数はす

べて、それが表す実体(オブジェクト)ではなく、それへの参照として統一的に扱

われています。

13.1 情報の参照と複製、その得失

情報を参照することと複製することには得失があります。実世界で以下のような

ことを考えてましょう。

A さん:B さん、先日の会議の資料をいただけませんか?

B さん:その棚にあるから、適当に使ってください。

数日後

B さん:A さん、先日の会議の資料を返していただけませんか?

A さん:適当に使ってくださいと言われたので、報告書に必要な部分を切り

抜いてしまいました。残りをお返ししすればいいですか?

困りましたね。A さんと B さんが同じ資料を共有していたために、B さんが資料

に手を加えた結果が A さんにも及んでしまうのです。この場合、資料の複製を作っ

て A さんに渡すべきでした。

一方、A さんが資料の1部を閲覧したいだけなら、複製を作ることは手間ですし、

A さんに B さんの作業の一部をお願いするなら、同じ資料を使ったほうが効果的で

す。

コンピュータ上では、情報を複製することは紙の資料などに比べれば容易ですが、

それでも大量の情報を扱う場合には複製に要する時間のため実行効率が問題になっ

てきます。害がないときは参照で同じ情報を見るようにし、独立に作業する場合に

複製するのが効果的です。

Page 36: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

13 コラム 参照と複製 次の章へ 目次へ

35

13.2 ミュータブルとイミュータブル

プログラミング言語によって参照の扱いは異なります。C 言語や Java では、単

なる数値は参照ではなく値そのものを変数自身が保持します。

他方、Python では変数はすべてオブジェクトへの参照として扱われますが、オブ

ジェクトそのものの扱いをデータの種類によって区別することで、混乱をさける方

針がとられています。そのための方法として値の変更を許すオブジェクト(ミュー

タブルといいます)と許さないオブジェクト(イミュータブル)を定めています。

Python では数値や文字列は値の変更を許さないイミュータブルなオブジェクトと

して扱われます。以下の例を見てみましょう。

a = 1

b = a

b = 2

この例は内部では以下のように動作します。

1行目:イミュータブルなオブジェクト「1」が作られ、その参照が a に代入さ

れる。

2行目:a の1への参照が、b にも設定される。

この時点で a と b は同じ参照を持ちます。

3行目:オブジェクト「1」はイミュータブルなので、これを「2」に書き換え

るのではなく、別のイミュータブルなオブジェクト「2」が作られ、それへの参照

が b に代入されます。この時点で a と b は異なるオブジェクトへの参照をもちま

す。したがって a の値は1のままです。仕組みは異なりますが、数値の値を直接、

変数が持つ他のプログラミング言語の利用者にも違和感なく使えます。

一方、リストは内容の書き換えを許すミュータブルなオブジェクトとして扱われ

ます。

a = [1, 2]

b = a

b[0] = 2

という操作では a も b も同じミュータブルなリストへの参照を持ったままで、3 行

Page 37: Title (2020): 1-200 Issue Date URL …...1. コラム Float って? 1.1 浮動小数点数 Python で小数を扱うデータに変換する関数は float() です。プカプカ浮かぶとい

13 コラム 参照と複製 次の章へ 目次へ

36

の代入操作により、リストの内容が変更されますので a の値も [2, 2] になります。

プログラミングで注意が必要な箇所は主としてミュータブルなオブジェクトを持

つ変数について以下のようなことを行う場合です。

⚫ 変数への他の変数を代入するとき。

⚫ 関数(メッソド)の引数として指定するとき。

これらの場合、新たな変数や関数のなかで値を独立に変更する必要がある場合は

複製を作る必要があるのです。