Pythonロボティクスコース レッスン 4

プログラムを簡潔にまとめるために使われる「関数」について学ぼう

このレッスンで学ぶこと

このレッスンでは、プログラムを簡潔にまとめるために使われる「関数」について学習していきます。レッスンの最後では、Studuino:bitのブザーから曲を流すときに、そのキーの高さを自由に設定できる処理を関数としてまとめる課題に取り組みます。

Pythonの関数

実際に社会の中で使われているシステムは、数万行を超える量のコードでそのプログラムが書かれています。そのような大きなプログラムほど、これから説明する「関数」を使って、簡潔にコードが記述されています。簡潔なコードは誰が見ても理解できるように整理されているため、メンテナンスの点でもとても優れています。

関数(function)という言葉は、数学の世界でも出てきます。Pythonにおける関数も、数学の関数とほとんど同じです。数学で「y = f(x)」という式で表される関数は、「x」という変数で定義された計算式「f(x)」 があり、x に何らかの数値を代入して計算すると、1つの結果「y」 が得られるというものです。

例として、次の関数を考えてみましょう。

f(x) = 2x + 3

この関数では、変数「x」に「1」を代入した場合は結果が「5」に、「2」を代入した場合は結果が「7」になります。

f(1) = 2×1 + 3 = 5
f(2) = 2×2 + 3 = 7

つまり、変数に何らかの値を与えると、それが処理されて、何らかの結果が得られるものが関数です。プログラムの世界では、関数に与える値を「引数」、関数を処理して得られた結果を「戻り値」や「返り値」と言います。ただし、プログラムでは数学とは違い、引数や戻り値のない関数も作成できます。

2. 1 Pythonの組み込み関数

Pythonにはあらかじめ用意されている関数があります。これらは「組み込み関数」といい、これまで何度か使ってきたprint()type()int()なども実は組み込み関数です。

これまでに使用してきた組み込み関数の一覧
関数名引数戻り値動作
print()数値や文字列などのデータなし引数として受け取ったデータを画面(ターミナル)に出力する。
int()数値または文字列のデータ整数のデータ整数ではないデータを引数として受け取り、整数型のデータに変換して返します。
float()数値または文字列のデータ浮動小数点数のデータ浮動小数点数ではないデータを引数として受け取り、浮動小数点数型のデータに変換して返します。
str()数値データ文字列のデータ数値データを引数として受け取り、文字列型のデータに変換して返します。
len()文字列などのデータデータの長さ引数として受け取ったデータの長さ(文字列の場合は文字数)を返します。
※関数名の意味:integer(整数)と、string(文字列) 、 「長さ」を意味する「length(レングス)」

Pythonの関数では、関数に与えるデータのことを引数、関数が処理して得られた結果のことを戻り値といいました。引数は1つの場合もあれば2つ以上、もしくはない場合もあります。戻り値も同様に、何らかの結果が得られる関数もあれば、print()のように画面に表示するだけの関数もあります。

上記以外にもPythonには多くの組み込み関数が用意されています。その他の組み込み関数について知りたい場合は、次のPython公式ドキュメントを参照してください。ただし、少し内容が難しいため、他のレッスンを終えてから読むことをお勧めします。

組み込み関数 – Python 3.6 ドキュメント

2. 2 関数を定義する

関数の中で行いたい処理はその次の行から書いていきますが、このとき、1つ気を付けなければならないことがあります。それは関数内のコードは先頭にインデント(空白文字)を付けるということです。インデントがない場合、Pythonは関数内のコードであることを認識できません。

では練習として、 引数「x」を受け取り、「x」を2乗した結果を戻り値として返す関数「square」 を定義し、色々な数値を渡して結果を表示してみましょう。

※「square」は英語で「正方形」のほかに「2乗」を意味します。このように関数にはできるだけ、内部のコードを読まなくても、どのような振る舞いを行うのかが分かるような名前をつけるように心掛けてください。

コードはMuのエディタエリアに書いていきます。 まずは、名前をsquareとし、引数xを受け取る関数を定義します。

  1. def square(x):

次に関数内のコードを書きます。引数xを2乗した結果を変数resultに代入します。インデント(半角スペース4個分)を忘れないように注意しましょう。

※「result」は英語で「結果」を意味します。
  1. def square(x):
  2.   result = x**2

変数resultを戻り値として返します。関数から値を返すときは、「return文」を使います。次のように書きましょう。

  1. def square(x):
  2.   result = x**2
  3.   return result

これで関数が定義できました。画面上方の「実行」ボタンをクリックして、このプログラムを実行しましょう。

関数は定義して実行しただけでは何も結果は得られません。関数は呼び出して使う必要があります。ターミナルに次のコードを入力し、呼び出した関数square()で「10の2乗」を計算してみましょう。

>>> square(10)
100

このように「関数名(引数)」の形式で関数を呼び出すことができます。引数を他の値に変えても同じように2乗した結果が得られることを確認してみましょう。

  • 「123の2乗」の計算

>>> square(123)
15129

  • 「1.2の2乗」の計算

>>> square(1.2)
1.44

ここでは、2乗の計算を行う関数を定義しましたが、このくらいであれば関数を定義せずに演算子「 ** 」で直接計算しても良さそうです。しかし、何十行にも渡るコードで複雑な計算を行う場合はどうでしょうか。実行する度に毎回式を書くのはとても大変です。そんなとき、必要な引数だけを入力すると結果を返してくれる関数を用意しておくと、プログラムを簡潔にまとめることができます。

プログラムの動作を説明するためのコメント

変数や関数の名前は、それらがプログラムの中でのどのような役割をもつのかが分かるように付けることが大切だと学びました。ですが、名前だけではコードを読む人に十分な情報を提供できないこともあります。そのようなときは、より詳しい情報を「コメント」として残します。

3. 1 コメントの書き方

プログラムに文字列データでも変数名でもない「ただの文字」を記述すると、エラーになります。そのためPythonでは、先頭に「 # 」をつけてコメントを書くというきまりがあります。次の利用例を見てみましょう。(9、12行目のシングルクオーテーションを書き直してください)

  1. # コメントでは、日本語を使うこともできます。
  2. a = 10 # 変数に10を代入
  3. b = 20 # 変数に20を代入
  4. # 下のコードでは変数aを上書きしていますが、#でコメント化しているため実行されません。
  5. # a = 50
  6. c = a + b
  7. ‘ ‘ ‘
  8. このようにクォーテーションを3つ重ねた内側に記述することで、
  9. 複数行に渡るコメントを残すこともできます。
  10. ‘ ‘ ‘
  11. print(c)

このプログラムを実行すると、次のような結果になります。

>>>
raw REPL; CTRL-B to exit
>OK
30

途中でa = 50と変数aを上書きするコードがありましたが、その行をコメント化しているため、最初に定義したa = 10で計算されて「30」が結果として表示されています。

このように、コメントはただのメモです。プログラムを処理する上では無視されます。「#」を使う場合は、この記号の後ろから行末までが全てコメントという扱いです。次の行の先頭からは普通にPythonのコードを記述できます。また、「#a = 50」のように、特定の命令の行頭に#をつけることで、一旦保留にしておきたい処理を無効化することもできます。もしまた、再度その処理が必要になったときは、#を削除するだけで済むのでとても便利です。

また、9行目~12行目のように、3個連続したクォーテーション(「’’‘」や「”””」)囲みコメント化する仕組みを「ヒアドキュメント」といいます。長文になる説明や、複数行に渡りコードを無効化したい場合に使います。

コメントは、自分の作ったコードを他の人に見せるときや、以前に自分自身で作ったコードを忘れた頃に見返すときに、どういう意図でそのコードを記述したかを理解する助けになります。変数名の付け方とあわせて効果的に活用してください。

課題:Studuino:bitのブザーから鳴らす音を関数にまとめる

テーマ.1-2では、変数を利用してStuduino:bitのブザーから流れる曲のテンポを制御しました。ここでは、引数に「0~5」の6段階でキーの高さを指定することで、音域を変えて曲を流す関数を定義します。

4. 1 プログラムの作成

はじめに、Studuino:bitのブザーと時間の制御を行うための準備コードを書きます。以下のコードをコピーして、エディタエリアに貼り付けましょう。

  1. from pystubit.board import buzzer
  2. import time

次に、キーの高さを引数として、ブザーか曲を流す関数play_music(key)を定義します。以下のように4行目にコードを追加しましょう。

  1. from pystubit.board import buzzer
  2. import time
  3.  
  4. def play_music(key):
【サンプルコード 4-1-1】
  1. from pystubit.board import buzzer
  2. import time
  3.  
  4. def play_music(key):
  5.   buzzer.on(str(55+key*12))
  6.   time.sleep_ms(600)
  7.   buzzer.on(str(60+key*12))
  8.   time.sleep_ms(600)
  9.   buzzer.on(str(59+key*12))
  10.   time.sleep_ms(300)
  11.   buzzer.on(str(60+key*12))
  12.   time.sleep_ms(300)
  13.   buzzer.on(str(62+key*12))
  14.   time.sleep_ms(600)
  15.   buzzer.on(str(60+key*12))
  16.   time.sleep_ms(300)
  17.   buzzer.on(str(62+key*12))
  18.   time.sleep_ms(300)
  19.   buzzer.on(str(64+key*12))
  20.   time.sleep_ms(300)
  21.   buzzer.on(str(64+key*12))
  22.   time.sleep_ms(300)
  23.   buzzer.on(str(65+key*12))
  24.   time.sleep_ms(300)
  25.   buzzer.on(str(64+key*12))
  26.   time.sleep_ms(300)
  27.   buzzer.on(str(57+key*12))
  28.   time.sleep_ms(600)
  29.   buzzer.off()

各高さの音を鳴らすコードは以下の形式で書いています。

buzzer.on(str(基準キーのMIDIノート番号 + 変数「key」*12))

buzzeron()という命令で「()」の中に指定する音の高さは、「オクターブ付きの音名」かもしくは、「MIDIと呼ばれる世界標準の規格で定められたノート番号」のどちらかで表します。ただし、指定するときはどちらも文字列にしておく必要があります。

MIDIノート番号表
オクターブ付きの音名(英語名)音名(日本語名)MIDIノート番号
C3ド348
D3レ350
E3ミ352
F3ファ353
G3ソ355
A3ラ357
B3シ359
C4ド460
D4レ462
E4ミ464
F4ファ465
G4ソ467
A4ラ469
B4シ471
C5ド572

1オクターブ高い音になると、MIDIノート番号は12ずつ増えます。例えば、C3とC4では、「60-48=12」となり、F3とF4でも「65-53=12」と同じ結果となります。

この性質を利用して、C3が含まれる1オクターブの範囲を基準として、そこから1オクターブ分キーが高くなる(変数keyが1増える)たびに、12ずつMIDIノート番号も増える計算式「50+key*12」を立てています。MIDIノート番号で音の高さを指定するときも、文字列である必要があるため、計算結果を標準関数のstr()で数値から文字列に変換しています。

4. 2 プログラムの実行

これで関数の定義ができました。画面上方の「実行」ボタンをクリックしてこのプログラムを実行しましょう。

実行したプログラムで定義された関数は、ターミナルから呼び出して実行することができました。以下のコードをターミナルに入力して、「Enter」キーで実行しましょう。

>>> play_music(0)

無事、曲が流れることが確認できたら、今度は引数に1~5の数字を順番に指定して実行し、段々と音域の高い所で曲が流れることを確認しましょう。

>>> play_music(1)
>>> play_music(2)
>>> play_music(3)
>>> play_music(4)
>>> play_music(5)

もし、このとき引数に6以上の数値や-1以下の整数値を指定するとエラーが起きます。これは、「50+key*12」の計算結果がStuduino:bitのブザーから鳴らせるMIDIノート番号の範囲「48~127」の外にあるためです。

おわりに

5. 1 このレッスンのまとめ

本レッスンでは、Pythonの「関数」と「コメント」について学びました。関数には、ここでは紹介ができなかった便利な機能や使い方が他にもあります。これらについては、学習を続けていく中で少しずつ説明をしていきます。今はまず、このレッスンを通して学習した関数の使い方をしっかりとおさえておきましょう。

5. 2 次回のレッスンについて

次回のレッスンでは、Pythonをはじめとする「オブジェクト指向」と言われるプログラミング言語の中心となる「オブジェクト」について、その基本を学習します。

TOP