Pythonロボティクスコース レッスン 13 *
テーマ.3-4 関数やメソッドの様々な引数
関数やメソッドで使われる3種類の引数について学ぼう
チャプター1
このレッスンで学ぶこと
このレッスンでは、関数やメソッドで使われる3種類の引数「位置引数」「キーワード引数」「デフォルト引数」について学習します。また、複数の引数が使われているLEDディスプレイの制御メソッドについて、その使い方をより詳しく見ていきます。
チャプター2
関数やメソッドの3種類の引数
これまで、様々な関数やメソッドを利用して、プログラムを作成してきましたが、同じメソッドでも、渡す引数の数や引数へ値を渡すときの書き方が違うことがありました。
【 例:StudinoBitDisplayクラスのscroll()
メソッド 】
1. from pystubit.board import display
2.
3. display.scroll('hello')
4. display.scroll('hello', 50)
5. display.scroll('hello', color=(15, 15, 15))
このように、1つのメソッドが複数の引数の渡し方に対応できるのは、pythonに「位置引数」「キーワード引数」「デフォルト引数」の3種類の引数が用意されているためです。
2. 1 位置引数について
指定する順番(位置)が決められた引数を「位置引数」といいます。例として、引数に指定した回数だけメッセージの表示を繰り返す以下のプログラムをつくり、位置引数の性質を確認しましょう。
【サンプルコード 2-1-1】
1. from pystubit.board import display
2.
3. def repeat_message(msg, num):
4. for i in range(num):
5. display.scroll(msg)
※英語では、「繰り返す」ことを「repeat」といいます。
repeat_message()
関数は2つの引数を持っています。第1引数のmsg
が表示するメッセージで、第2引数のnum
がメッセージの表示を繰り返す回数です。このような形式で定義した引数は位置引数となります。
では、このプログラムを実行します。一度実行したプログラム内で定義されている関数は、ターミナルからも呼び出すことができます。ターミナルに、次のコードを入力して関数を呼び出しましょう。
>>> repeat_message('hello', 3)
上のコードを実行すると、LEDディスプレイにhelloというメッセージが3回繰り返しスクロールされます。位置引数は順番が決められているため、上のコードで2つの引数の位置を逆にして指定すると、関数内部の処理でエラーが発生し、意図した動作となりません。実際に引数を逆にして呼び出してみましょう。
>>> repeat_message(3,"hello") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 5, in repeat_message TypeError: unsupported types for __lt__: 'int', 'str'
出力された最後の行にTypeError:
とありますが、これは型に関するエラーが起きたこと表しています。続きを読むと、__lt__
というメソッドを実行するときに、想定していないint型(整数型)とstr型(文字列型)の値が入力されたため、エラーが発生したことが書かれています。
__lt__(a, b)
は「a < b」の比較演算に対応した特殊なメソッドで、オブジェクトごとに決められた比較処理を行うために使われます。このメソッドがint型とstr型の比較に対応していないことから、エラーが発生していました。実際に、下のコードをターミナルに入力して、整数値と文字列を「<」で比較すると、同じエラーが発生することを確認しましょう。
>>> 1 < 2 True >>> 'aa' < 'ab' True >>> 1 < 'a' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported types for __lt__: 'int', 'str'
※数値の場合は単純に値が小さいかどうかを比較し、文字列の場合は本の辞書順で並べたときに先に出るかどうか(辞書では’aa’の方が’ab’より先に出る)を比較しています。最後の「1 < ‘a’」は比較することを想定していない2つの異なる型を入力したため、エラーメッセージが表示されています。
2. 2 キーワード引数について
「キーワード引数」は、特定の引数と値が1対1でひもづくように、「引数名 = 値」のフォーマットで指定する引数です。位置引数の説明で作成した関数を、キーワード引数を使って呼び出してみましょう。
>>> repeat_message(msg='hello', num=3)
同じように、ディスプレイに「hello」と3回繰り返しスクロールされるため、これだけを見ると、引数名を付けた分だけ、コードを長く書かなければならず、あまりメリットがないように思えます。しかし、キーワード引数には指定する位置を逆にしてもエラーなく実行できるというメリットがあります。今度は以下のコードをターミナルで実行してみましょう。
>>> repeat_message(num=3, msg='hello')
さきほどとは違い、エラーになりません。また、関数を定義するときに、「 *(アスタリスク)」を追記すると、それ以降の引数はすべてキーワード引数としての指定を強制できます。下のように【サンプルコード 2-1-1】を変更し、もう一度Studuino:bitに転送して実行しましょう。
【 サンプルコード 2-2-1 】
変更【3行目】
1. from pystubit.board import display
2.
3. def repeat_message(msg, *, num):
4. for i in range(num):
5. display.scroll(msg)
引数名numを省略して値を渡すと、エラーが発生するようになりました。
>>> repeat_message('hello', 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: function takes 1 positional arguments but 2 were given
2. 3 デフォルト引数について
「デフォルト引数」は値が省略された場合に、初期値として用意した値が代入される引数です。関数を定義するときに「引数名 = 初期値」のフォーマットで指定します。前の【 サンプルコード 2-2-1 】から引数num
に初期値として「1」を渡すように変更しましょう。
変更【3行目】
1. from pystubit.board import display
2.
3. def repeat_message(msg, *, num=1):
4. for i in range(num):
5. display.scroll(msg)
このプログラムを実行します。ターミナルで引数num
を省略して関数を呼び出すと、1回だけメッセ―ジがスクロールされます。これは、引数num
に初期値の1が代入されて関数内部の処理が行われるためです。
>>> repeat_message('hello')
チャプター3
StuduinoBitDisplayクラスのメソッドの引数
「位置引数」「キーワード引数」「デフォルト引数」の3つの引数をうまく組み合わせることで、柔軟な使い方ができる関数やメソッドが定義できます。実際に、Studuino:bitの各クラスのメソッドでも3つの引数が使い分けられています。特に、StuduinoBitDisplayクラスのshow()
メソッドとscroll()
メソッドはこれらの引数を利用することで様々な使い方ができるように工夫されています。
3. 1 `show()`メソッドの引数について
StuduinoBitDisplayクラスのshow()メソッドは次のように定義されています。
def show(iterable, delay=400, *, wait=True, loop=False, clear=False, color=None):
- iterable:位置引数
LEDディスプレイに表示する文字列もしくはStuduinoBitImageクラスのオブジェクトの配列(リストもしくはタプル)を指定します。ただし、StuduinoBitImageクラスのオブジェクトを1つだけ指定する場合は、リストやタプルにまとめる必要はありません。 - delay:位置引数、デフォルト引数
次の文字やイメージに表示が切り替わるまでの時間をミリ秒単位で指定します。 - wait:キーワード引数、デフォルト引数
Trueを指定した場合、表示が完了するまで次の行のコードの処理を待ちます。 - loop:キーワード引数、デフォルト引数
Trueを指定した場合、表示を繰り返します。 - clear:キーワード引数、デフォルト引数
Trueを指定した場合、このメソッドの実行完了後にLEDディスプレイの表示がクリアされます。 - color:キーワード引数、デフォルト引数
表示する文字列やイメージの色を指定します。
このように、show()
メソッドには全部で6つの引数があり、iterable
以外はすべてデフォルト引数になっています。またwait以降の引数は値を渡すときに、キーワード引数として指定することが強制されています。
では、実際にそれぞれの引数の値を変更して、動作がどのように変わるのかを確認していきましょう。
■ 引数iterable
の変更
引数iterable
には、文字列とStuduinoBitImageクラスのインスタンスを渡すことができます。StuduinoBitImageクラスのインスタンスはタプルやリストにまとめて渡すこともできます。
1. from pystubit.board import display, Image
2.
3. display.show('hello')
4.
5. img = Image('11111:11111:11111:11111:11111')
6. display.show(img)
7.
8. img1 = Image('10101:01010:10101:01010:10101')
9. img2 = Image('01010:10101:01010:10101:01010')
10. display.show((img1, img2)) #(img1, img2)のタプルを渡している
■ 引数delay
の変更(表示速度の変更)
初期値では「delay=400
」となっているため、例えば、「delay=100
」と指定することで、その4倍の速さで表示が切り替わります。
1. from pystubit.board import display
2.
3. display.show('hello', delay=100)
■ 引数wait
の変更(次のコードの実行を待つ処理と待たない処理)
以下のコードでは、文字列を表示させる処理とブザーを鳴らす処理を順番に実行しています。初期値である「wait=True
」の場合は、文字列の表示を終えたあとでブザーが鳴ります
1. from pystubit.board import display, buzzer
2. import time
3.
4. display.show('hello', wait=True)
5. buzzer.on('C4')
6. time.sleep_ms(1000)
7. buzzer.off()
反対に、「wait=False
」を指定すると、LEDディスプレイへの文字列の表示処理とブザー音を鳴らす処理がほぼ同時に実行されるようになります。
変更【4行目】
1. from pystubit.board import display, buzzer
2. import time
3.
4. display.show('hello', wait=False)
5. buzzer.on('C4')
6. time.sleep_ms(1000)
7. buzzer.off()
■ 引数loop
の変更(表示を無限に繰り返す)
「loop=True
」を指定すると「While True:
」で囲むのと同じように、表示を無限に繰り返します。表示を止めるときは、Studuino:bitのリセットボタンを押してください。
1. from pystubit.board import display
2.
3. display.show("hello", loop=True)
■ 引数clear
の変更(表示処理終了後に表示をクリアする)
初期値の「clear=False
」の場合、最後に表示されたイメージがそのままLEDディスプレイ上に表示され続けますが、「clear=True
」を指定するとLEDディスプレイの表示が最後にクリアされるようになります。
1. from pystubit.board import display
2.
3. display.show("hello", clear=True)
■ 引数color
の変更(表示色の変更)
「color=None
」で初期値として指定している「None」は何もないことを表す特別なオブジェクトです。Noneの場合、ディスプレイには赤色で表示されるようになっています。下の例では、「color=(31, 31, 31)
」と色のRGB値をタプルで指定することで、LEDディスプレイの点灯色を白色に設定しています。
1. from pystubit.board import display
2.
3. display.show("hello", color=(31, 31, 31))
3. 2 `scroll()`メソッドの引数について
scroll()
メソッドは、次のように定義されています。
def scroll(string, delay=150, *, wait=True, loop=False, color=None):
- string:位置引数
LEDディスプレイにスクロールする文字列を指定します。 - delay:位置引数、デフォルト引数
表示が1ピクセル分左にシフトするまでの時間をミリ秒単位で指定します。 - wait:キーワード引数、デフォルト引数
Trueを指定した場合、スクロールが完了するまで次の行のコードの処理を待ちます。 - loop:キーワード引数、デフォルト引数
Trueを指定した場合、スクロールを繰り返します。 - color:キーワード引数、デフォルト引数
スクロールする文字列やイメージの色を指定します。
scroll()
メソッドは、show()
メソッドと似た引数を持っているため、それぞれの細かな説明は省略します。show()
メソッドとの違いとして、スクロールの対象が文字列のみとなっている点とスクロール後はかならずLEDディスプレイがクリアされるため、引数clear
がない点をおさえておきましょう。ここまでできたらクリック
チャプター4
課題:曲に合わせてLEDディスプレイの表示が変わる電子オルゴールのプログラム作成
ここまでで学習した内容を踏まえて、曲の再生に合わせてLEDディスプレイの表示が切り替わる電子オルゴールのプログラムを作成しましょう。
【 電子オルゴールの曲:ABCのうた】
4. 1 プログラムの作成
まずは、アルファベット「ABCDEFG」を順番にLEDディスプレイの表示する処理を書きます。LEDディスプレイ表示処理中にブザー音を鳴らすため、引数wait
の値はFalse
にしておく必要があります。また、引数delay
は音の長さと合わせます。基準となる四分音符を600ミリ秒に、半音符を1200ミリ秒に設定すると、A~Fまでは600ミリ秒間、Gは1200ミリ秒間表示することになります。それぞれdelay=600
とdelay=1200
を指定しましょう。
1. from pystubit.board import display
2.
3. display.show('ABCDEF', delay=600, wait=False)
4. display.show('G', delay=1200, wait=False, clear=True)
続けて、音を鳴らすコードを書きます。StuduinoBitBuzzerクラスのon
メソッドは、次のように引数が定義されています。引数duration
に音を鳴らす間隔を指定すると、その時間の経過後ブザー音が止まるようになっています。
def on(sound, *, duration=-1):
そこで、四分音符の音を鳴らす場合はduration=600
を、半音符の音を鳴らす場合はduration=1200
を指定します。また、最初にdisplay.show(...)
が実行されてからLEDディスプレイに文字が表示されるまでは少し時間が空くため、ブザーを鳴らすコードの実行を500ミリ秒だけ遅らせることで、文字の表示と音がきれいにそろいます。
【 サンプルコード 4-1-1 】
追加・変更【1行目、2行目、5行目~11行目、13行目】
1. from pystubit.board import display, buzzer
2. import time
3.
4. display.show('ABCDEFG', delay=600, wait=False)
5. time.sleep_ms(500)
6. buzzer.on('C4', duration=600)
7. buzzer.on('C4', duration=600)
8. buzzer.on('G4', duration=600)
9. buzzer.on('G4', duration=600)
10. buzzer.on('A4', duration=600)
11. buzzer.on('A4', duration=600)
12. display.show('G', delay=1200, wait=False, clear=True)
13. buzzer.on('G4', duration=1200)
チャプター5
おわりに
5. 1 このレッスンのまとめ
このレッスンでは関数やメソッドで使われる次の3つの引数について学習しました。
- 位置引数・・・指定する順番(位置)が決められている引数。
- キーワード引数・・・「引数名=値」で指定する引数。
- デフォルト引数・・・呼び出し時に値が省略された場合、代わりに初期値が代入される引数
これらの引数は今後、独自の関数やメソッドを定義していくときに、使い分けて利用していきますので、しっかりと復習しておきましょう。
5. 2 次回のレッスンについて
次回からテーマ.4に入ります。テーマ.4では、テーマ.3で紹介してきたArtecRoboやStuduino:bitの新しい機能を使い、ブロックで形を組み立て、センサーを利用したモーターやLEDディスプレイ、ブザーの制御を行っていきます。ここまでできたらクリック
チャプターを全部クリアしよう!